]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #51678 - Zoxc:combine-lints, r=estebank
authorbors <bors@rust-lang.org>
Tue, 26 Jun 2018 14:18:13 +0000 (14:18 +0000)
committerbors <bors@rust-lang.org>
Tue, 26 Jun 2018 14:18:13 +0000 (14:18 +0000)
Combine all builtin late lints

420 files changed:
src/Cargo.lock
src/bootstrap/builder.rs
src/bootstrap/dist.rs
src/bootstrap/lib.rs
src/bootstrap/test.rs
src/doc/rustdoc/src/documentation-tests.md
src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md [new file with mode: 0644]
src/liballoc/vec.rs
src/libcore/cmp.rs
src/libcore/iter/traits.rs
src/libcore/marker.rs
src/libcore/mem.rs
src/libcore/ops/index.rs
src/libcore/option.rs
src/libproc_macro/quote.rs
src/librustc/cfg/construct.rs
src/librustc/diagnostics.rs
src/librustc/hir/intravisit.rs
src/librustc/hir/lowering.rs
src/librustc/hir/map/blocks.rs
src/librustc/hir/map/collector.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/hir/print.rs
src/librustc/ich/impls_hir.rs
src/librustc/ich/impls_syntax.rs
src/librustc/ich/impls_ty.rs
src/librustc/infer/anon_types/mod.rs
src/librustc/infer/canonical.rs
src/librustc/infer/error_reporting/mod.rs
src/librustc/infer/higher_ranked/mod.rs
src/librustc/infer/lexical_region_resolve/README.md
src/librustc/infer/region_constraints/README.md
src/librustc/lint/builtin.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/reachable.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/stability.rs
src/librustc/mir/mod.rs
src/librustc/traits/auto_trait.rs
src/librustc/traits/coherence.rs
src/librustc/traits/error_reporting.rs
src/librustc/traits/mod.rs
src/librustc/traits/object_safety.rs
src/librustc/traits/select.rs
src/librustc/traits/specialize/mod.rs
src/librustc/traits/structural_impls.rs
src/librustc/ty/fold.rs
src/librustc/ty/item_path.rs
src/librustc/ty/mod.rs
src/librustc/ty/sty.rs
src/librustc/util/ppaux.rs
src/librustc_allocator/Cargo.toml
src/librustc_allocator/expand.rs
src/librustc_allocator/lib.rs
src/librustc_borrowck/borrowck/README.md
src/librustc_borrowck/borrowck/mod.rs
src/librustc_codegen_llvm/attributes.rs
src/librustc_codegen_llvm/diagnostics.rs
src/librustc_data_structures/obligation_forest/mod.rs
src/librustc_driver/driver.rs
src/librustc_driver/pretty.rs
src/librustc_lint/bad_style.rs
src/librustc_lint/builtin.rs
src/librustc_lint/lib.rs
src/librustc_lint/types.rs
src/librustc_metadata/creader.rs
src/librustc_metadata/cstore_impl.rs
src/librustc_metadata/encoder.rs
src/librustc_mir/borrow_check/error_reporting.rs
src/librustc_mir/borrow_check/mod.rs
src/librustc_mir/borrow_check/used_muts.rs [new file with mode: 0644]
src/librustc_mir/build/scope.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_mir/hair/pattern/_match.rs
src/librustc_mir/hair/pattern/check_match.rs
src/librustc_mir/hair/pattern/mod.rs
src/librustc_mir/monomorphize/collector.rs
src/librustc_mir/transform/check_unsafety.rs
src/librustc_mir/util/borrowck_errors.rs
src/librustc_mir/util/collect_writes.rs
src/librustc_passes/ast_validation.rs
src/librustc_passes/diagnostics.rs
src/librustc_passes/hir_stats.rs
src/librustc_passes/loops.rs
src/librustc_passes/rvalue_promotion.rs
src/librustc_privacy/lib.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs
src/librustc_save_analysis/dump_visitor.rs
src/librustc_save_analysis/lib.rs
src/librustc_save_analysis/sig.rs
src/librustc_traits/chalk_context.rs
src/librustc_traits/lowering.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/cast.rs
src/librustc_typeck/check/compare_method.rs
src/librustc_typeck/check/method/confirm.rs
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/upvar.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/coherence/unsafety.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/diagnostics.rs
src/librustc_typeck/lib.rs
src/librustdoc/Cargo.toml
src/librustdoc/clean/auto_trait.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/clean/simplify.rs
src/librustdoc/core.rs
src/librustdoc/doctree.rs
src/librustdoc/html/format.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/rustdoc.css
src/librustdoc/lib.rs
src/librustdoc/visit_ast.rs
src/libstd/future.rs [new file with mode: 0644]
src/libstd/lib.rs
src/libstd/macros.rs
src/libstd/panic.rs
src/libstd/sys/mod.rs
src/libstd/sys/unix/fs.rs
src/libstd/sys/unix/rand.rs
src/libsyntax/ast.rs
src/libsyntax/attr.rs
src/libsyntax/codemap.rs
src/libsyntax/diagnostic_list.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/derive.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/placeholders.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/feature_gate.rs
src/libsyntax/fold.rs
src/libsyntax/lib.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/util/node_count.rs
src/libsyntax/util/parser.rs
src/libsyntax/visit.rs
src/libsyntax_ext/deriving/clone.rs
src/libsyntax_ext/deriving/cmp/eq.rs
src/libsyntax_ext/deriving/generic/mod.rs
src/libsyntax_ext/deriving/generic/ty.rs
src/libsyntax_ext/deriving/mod.rs
src/libsyntax_ext/env.rs
src/libsyntax_ext/proc_macro_registrar.rs
src/libsyntax_pos/hygiene.rs
src/libsyntax_pos/lib.rs
src/test/compile-fail/associated-types-unsized.rs
src/test/compile-fail/auxiliary/lint_stability.rs
src/test/compile-fail/bad-method-typaram-kind.rs
src/test/compile-fail/bad-sized.rs
src/test/compile-fail/builtin-superkinds-double-superkind.rs
src/test/compile-fail/builtin-superkinds-in-metadata.rs
src/test/compile-fail/builtin-superkinds-simple.rs
src/test/compile-fail/builtin-superkinds-typaram-not-send.rs
src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs
src/test/compile-fail/cross-borrow-trait.rs
src/test/compile-fail/destructure-trait-ref.rs
src/test/compile-fail/dst-bad-assign-2.rs
src/test/compile-fail/dst-bad-assign-3.rs
src/test/compile-fail/dst-bad-assign.rs
src/test/compile-fail/dst-bad-deep-2.rs
src/test/compile-fail/dst-bad-deep.rs
src/test/compile-fail/dst-object-from-unsized-type.rs
src/test/compile-fail/dst-sized-trait-param.rs
src/test/compile-fail/extern-types-not-sync-send.rs
src/test/compile-fail/extern-types-unsized.rs
src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs [new file with mode: 0644]
src/test/compile-fail/fn-trait-formatting.rs
src/test/compile-fail/issue-13033.rs
src/test/compile-fail/issue-14366.rs
src/test/compile-fail/issue-15756.rs
src/test/compile-fail/issue-17651.rs
src/test/compile-fail/issue-18107.rs
src/test/compile-fail/issue-18919.rs
src/test/compile-fail/issue-1900.rs
src/test/compile-fail/issue-20005.rs
src/test/compile-fail/issue-20433.rs
src/test/compile-fail/issue-20605.rs
src/test/compile-fail/issue-20939.rs
src/test/compile-fail/issue-21763.rs
src/test/compile-fail/issue-22874.rs
src/test/compile-fail/issue-23281.rs
src/test/compile-fail/issue-24446.rs
src/test/compile-fail/issue-27060-2.rs
src/test/compile-fail/issue-27078.rs
src/test/compile-fail/issue-32963.rs
src/test/compile-fail/issue-35988.rs
src/test/compile-fail/issue-38954.rs
src/test/compile-fail/issue-41139.rs
src/test/compile-fail/issue-41229-ref-str.rs
src/test/compile-fail/issue-42312.rs
src/test/compile-fail/issue-43431.rs
src/test/compile-fail/issue-5153.rs
src/test/compile-fail/issue-5883.rs
src/test/compile-fail/issue-7013.rs
src/test/compile-fail/kindck-impl-type-params.rs
src/test/compile-fail/kindck-nonsendable-1.rs
src/test/compile-fail/kindck-send-object.rs
src/test/compile-fail/kindck-send-object1.rs
src/test/compile-fail/kindck-send-object2.rs
src/test/compile-fail/kindck-send-owned.rs
src/test/compile-fail/kindck-send-unsafe.rs
src/test/compile-fail/lint-stability.rs
src/test/compile-fail/map-types.rs
src/test/compile-fail/no-send-res-ports.rs
src/test/compile-fail/no_send-enum.rs
src/test/compile-fail/no_send-rc.rs
src/test/compile-fail/no_send-struct.rs
src/test/compile-fail/non-interger-atomic.rs
src/test/compile-fail/not-panic-safe-2.rs
src/test/compile-fail/not-panic-safe-3.rs
src/test/compile-fail/not-panic-safe-4.rs
src/test/compile-fail/not-panic-safe-6.rs
src/test/compile-fail/not-panic-safe.rs
src/test/compile-fail/object-does-not-impl-trait.rs
src/test/compile-fail/object-safety-by-value-self-use.rs
src/test/compile-fail/privacy/associated-item-privacy-type-binding.rs
src/test/compile-fail/private-inferred-type.rs
src/test/compile-fail/range-1.rs
src/test/compile-fail/range_traits-1.rs
src/test/compile-fail/should-fail-no_gate_irrefutable_if_let_pattern.rs [new file with mode: 0644]
src/test/compile-fail/should-fail-with_gate_irrefutable_pattern_deny.rs [new file with mode: 0644]
src/test/compile-fail/str-idx.rs
src/test/compile-fail/str-mut-idx.rs
src/test/compile-fail/substs-ppaux.rs
src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
src/test/compile-fail/trait-item-privacy.rs
src/test/compile-fail/traits-negative-impls.rs
src/test/compile-fail/traits-repeated-supertrait-ambig.rs
src/test/compile-fail/trivial_casts.rs
src/test/compile-fail/type-mismatch-same-crate-name.rs
src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs
src/test/compile-fail/typeck-default-trait-impl-negation-send.rs
src/test/compile-fail/union/union-unsized.rs
src/test/compile-fail/unsized-bare-typaram.rs
src/test/compile-fail/unsized-enum.rs
src/test/compile-fail/unsized-inherent-impl-self-type.rs
src/test/compile-fail/unsized-struct.rs
src/test/compile-fail/unsized-trait-impl-self-type.rs
src/test/compile-fail/unsized-trait-impl-trait-arg.rs
src/test/compile-fail/unsized3.rs
src/test/compile-fail/unsized5.rs
src/test/compile-fail/unsized6.rs
src/test/compile-fail/unsized7.rs
src/test/compile-fail/wf-trait-fn-where-clause.rs
src/test/mir-opt/end_region_6.rs
src/test/mir-opt/end_region_7.rs
src/test/mir-opt/validate_1.rs
src/test/mir-opt/validate_5.rs
src/test/parse-fail/issue-20711-2.rs
src/test/parse-fail/issue-20711.rs
src/test/parse-fail/range_inclusive_dotdotdot.rs
src/test/parse-fail/removed-syntax-static-fn.rs
src/test/parse-fail/trait-non-item-macros.rs
src/test/parse-fail/trait-pub-assoc-const.rs
src/test/parse-fail/trait-pub-assoc-ty.rs
src/test/parse-fail/trait-pub-method.rs
src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs
src/test/run-pass/allow_irrefutable_let_patterns.rs [new file with mode: 0644]
src/test/run-pass/async-await.rs [new file with mode: 0644]
src/test/run-pass/issue-21058.rs
src/test/run-pass/issue-22777.rs
src/test/run-pass/issue-23435.rs [deleted file]
src/test/run-pass/issue-51655.rs [new file with mode: 0644]
src/test/ui/allocator-submodule.rs [new file with mode: 0644]
src/test/ui/allocator-submodule.stderr [new file with mode: 0644]
src/test/ui/anonymous-higher-ranked-lifetime.stderr
src/test/ui/arbitrary-self-types-not-object-safe.stderr
src/test/ui/async-fn-multiple-lifetimes.rs [new file with mode: 0644]
src/test/ui/async-fn-multiple-lifetimes.stderr [new file with mode: 0644]
src/test/ui/borrowck/borrowck-box-insensitivity.nll.stderr
src/test/ui/borrowck/issue-41962.rs
src/test/ui/borrowck/issue-41962.stderr
src/test/ui/borrowck/issue-51415.nll.stderr [new file with mode: 0644]
src/test/ui/borrowck/issue-51415.rs [new file with mode: 0644]
src/test/ui/borrowck/issue-51415.stderr [new file with mode: 0644]
src/test/ui/cast-to-unsized-trait-object-suggestion.stderr
src/test/ui/chalkify/lower_struct.rs [new file with mode: 0644]
src/test/ui/chalkify/lower_struct.stderr [new file with mode: 0644]
src/test/ui/chalkify/lower_trait_higher_rank.stderr
src/test/ui/closure-array-break-length.rs [new file with mode: 0644]
src/test/ui/closure-array-break-length.stderr [new file with mode: 0644]
src/test/ui/codemap_tests/unicode.stderr
src/test/ui/const-unsized.rs
src/test/ui/const-unsized.stderr
src/test/ui/did_you_mean/bad-assoc-ty.stderr
src/test/ui/did_you_mean/issue-40006.stderr
src/test/ui/edition-keywords-2018-2015-parsing.rs
src/test/ui/edition-keywords-2018-2015-parsing.stderr
src/test/ui/edition-keywords-2018-2018-parsing.rs
src/test/ui/edition-keywords-2018-2018-parsing.stderr
src/test/ui/error-codes/E0033-teach.stderr
src/test/ui/error-codes/E0033.stderr
src/test/ui/error-codes/E0110.stderr
src/test/ui/error-codes/E0131.stderr
src/test/ui/error-codes/E0277-2.rs
src/test/ui/error-codes/E0277-2.stderr
src/test/ui/error-codes/E0277.rs
src/test/ui/error-codes/E0277.stderr
src/test/ui/error-codes/E0558.stderr
src/test/ui/error-codes/E0648.rs [new file with mode: 0644]
src/test/ui/error-codes/E0648.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0657.rs
src/test/ui/error-codes/E0657.stderr
src/test/ui/fat-ptr-cast.stderr
src/test/ui/feature-gate-async-await-2015-edition.rs [new file with mode: 0644]
src/test/ui/feature-gate-async-await-2015-edition.stderr [new file with mode: 0644]
src/test/ui/feature-gate-async-await.rs [new file with mode: 0644]
src/test/ui/feature-gate-async-await.stderr [new file with mode: 0644]
src/test/ui/feature-gate-trivial_bounds.stderr
src/test/ui/fmt/send-sync.stderr
src/test/ui/generator/sized-yield.rs
src/test/ui/generator/sized-yield.stderr
src/test/ui/impl-trait/auto-trait-leak.rs
src/test/ui/impl-trait/auto-trait-leak.stderr
src/test/ui/impl-trait/auto-trait-leak2.rs
src/test/ui/impl-trait/auto-trait-leak2.stderr
src/test/ui/impl_trait_projections.rs
src/test/ui/impl_trait_projections.stderr
src/test/ui/in-band-lifetimes/impl/dyn-trait.stderr
src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
src/test/ui/interior-mutability/interior-mutability.rs
src/test/ui/interior-mutability/interior-mutability.stderr
src/test/ui/issue-17441.rs
src/test/ui/issue-17441.stderr
src/test/ui/issue-19100.fixed [new file with mode: 0644]
src/test/ui/issue-19100.rs
src/test/ui/issue-19100.stderr
src/test/ui/issue-20692.stderr
src/test/ui/issue-30302.stderr
src/test/ui/issue-50577.rs [new file with mode: 0644]
src/test/ui/issue-50577.stderr [new file with mode: 0644]
src/test/ui/issue-50585.rs [new file with mode: 0644]
src/test/ui/issue-50585.stderr [new file with mode: 0644]
src/test/ui/issue-50781.rs [new file with mode: 0644]
src/test/ui/issue-50781.stderr [new file with mode: 0644]
src/test/ui/issue-51022.rs
src/test/ui/issue-51022.stderr
src/test/ui/issue-51714.rs [new file with mode: 0644]
src/test/ui/issue-51714.stderr [new file with mode: 0644]
src/test/ui/lint-ctypes.rs
src/test/ui/lint-ctypes.stderr
src/test/ui/lint/trivial-casts-featuring-type-ascription.rs [new file with mode: 0644]
src/test/ui/lint/trivial-casts-featuring-type-ascription.stderr [new file with mode: 0644]
src/test/ui/lint/trivial-casts.rs [new file with mode: 0644]
src/test/ui/lint/trivial-casts.stderr [new file with mode: 0644]
src/test/ui/lub-glb/old-lub-glb-object.stderr
src/test/ui/mismatched_types/binops.rs
src/test/ui/mismatched_types/binops.stderr
src/test/ui/mismatched_types/cast-rfc0401.rs
src/test/ui/mismatched_types/cast-rfc0401.stderr
src/test/ui/mismatched_types/issue-19109.stderr
src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr
src/test/ui/moves-based-on-type-match-bindings.nll.stderr
src/test/ui/nll/issue-51512.rs [new file with mode: 0644]
src/test/ui/nll/issue-51512.stderr [new file with mode: 0644]
src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
src/test/ui/no-args-non-move-async-closure.rs [new file with mode: 0644]
src/test/ui/no-args-non-move-async-closure.stderr [new file with mode: 0644]
src/test/ui/parser/expected-comma-found-token.rs [new file with mode: 0644]
src/test/ui/parser/expected-comma-found-token.stderr [new file with mode: 0644]
src/test/ui/partialeq_help.stderr
src/test/ui/pub/pub-restricted.stderr
src/test/ui/resolve/issue-5035-2.rs
src/test/ui/resolve/issue-5035-2.stderr
src/test/ui/rfc1598-generic-associated-types/collections.stderr
src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr
src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr
src/test/ui/rfc1598-generic-associated-types/iterable.stderr
src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr
src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr
src/test/ui/single-use-lifetime/fn-types.stderr
src/test/ui/single-use-lifetime/one-use-in-fn-argument-in-band.stderr
src/test/ui/single-use-lifetime/one-use-in-fn-argument.stderr
src/test/ui/single-use-lifetime/one-use-in-inherent-impl-header.stderr
src/test/ui/single-use-lifetime/one-use-in-inherent-method-argument.stderr
src/test/ui/single-use-lifetime/one-use-in-inherent-method-return.stderr
src/test/ui/single-use-lifetime/one-use-in-trait-method-argument.stderr
src/test/ui/single-use-lifetime/two-uses-in-inherent-method-argument-and-return.stderr
src/test/ui/span/borrowck-object-mutability.nll.stderr
src/test/ui/struct-duplicate-comma.rs [new file with mode: 0644]
src/test/ui/struct-duplicate-comma.stderr [new file with mode: 0644]
src/test/ui/suggestions/auxiliary/macro-in-other-crate.rs [new file with mode: 0644]
src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr
src/test/ui/suggestions/dotdotdot-expr.rs [new file with mode: 0644]
src/test/ui/suggestions/dotdotdot-expr.stderr [new file with mode: 0644]
src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs
src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr
src/test/ui/suggestions/str-array-assignment.rs
src/test/ui/suggestions/str-array-assignment.stderr
src/test/ui/token/issue-41155.stderr
src/test/ui/trait-suggest-where-clause.rs
src/test/ui/trait-suggest-where-clause.stderr
src/test/ui/trivial-bounds-inconsistent-sized.stderr
src/test/ui/trivial-bounds-inconsistent.stderr
src/test/ui/trivial-bounds-leak.stderr
src/test/ui/type-check-defaults.rs
src/test/ui/type-check-defaults.stderr
src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
src/test/ui/union/union-sized-field.rs
src/test/ui/union/union-sized-field.stderr
src/test/ui/unsized-enum2.rs
src/test/ui/unsized-enum2.stderr
src/tools/build-manifest/src/main.rs
src/tools/rustfmt

index 615d36b8ee558174a7eae6f4783fb30a463f155b..b74587e566210aabb4878f9d67285590465753b5 100644 (file)
@@ -1220,7 +1220,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "minifier"
-version = "0.0.11"
+version = "0.0.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1813,10 +1813,10 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-arena"
-version = "156.0.0"
+version = "164.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rustc-ap-rustc_data_structures 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1830,7 +1830,7 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_cratesio_shim"
-version = "156.0.0"
+version = "164.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1856,7 +1856,7 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_data_structures"
-version = "156.0.0"
+version = "164.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1864,8 +1864,8 @@ dependencies = [
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_cratesio_shim 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1887,13 +1887,13 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_errors"
-version = "156.0.0"
+version = "164.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1911,13 +1911,13 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_target"
-version = "156.0.0"
+version = "164.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_cratesio_shim 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1927,7 +1927,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "rustc-ap-serialize"
-version = "156.0.0"
+version = "164.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1947,16 +1947,16 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-syntax"
-version = "156.0.0"
+version = "164.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_errors 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_target 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_errors 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_target 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1974,12 +1974,12 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-syntax_pos"
-version = "156.0.0"
+version = "164.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rustc-ap-arena 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-arena 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2035,6 +2035,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 name = "rustc_allocator"
 version = "0.0.0"
 dependencies = [
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_target 0.0.0",
@@ -2425,7 +2426,7 @@ dependencies = [
 name = "rustdoc"
 version = "0.0.0"
 dependencies = [
- "minifier 0.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "minifier 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2494,8 +2495,8 @@ dependencies = [
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_target 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_target 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3262,7 +3263,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum mdbook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "90b5a8d7e341ceee5db3882a06078d42661ddcfa2b3687319cc5da76ec4e782f"
 "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
 "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
-"checksum minifier 0.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "26f3e36a4db1981b16567e4abfd6ddc3641bc9b950bdc868701f656bf9b74bdd"
+"checksum minifier 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "78cb57f9a385530d60f2d67f6e108050b478b7a0ffd0bb9c350803e1356535dd"
 "checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4"
 "checksum miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9224c91f82b3c47cf53dcf78dfaa20d6888fbcc5d272d5f2fcdf8a697f3c987d"
 "checksum nibble_vec 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c8d77f3db4bce033f4d04db08079b2ef1c3d02b44e86f25d08886fafa7756ffa"
@@ -3317,21 +3318,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a"
 "checksum rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be231e1e559c315bc60ced5ad2cc2d7a9c208ed7d4e2c126500149836fda19bb"
 "checksum rustc-ap-arena 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e794b25832224eea9252ebfa9f94ab7070d0a60c977793112c611501cb56b48d"
-"checksum rustc-ap-arena 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83e91a01cd6c5a9e4f68c2b5c81b62b172aa9e00fc2fec862c0899e3fac1fd32"
+"checksum rustc-ap-arena 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f0687e373d86505f31faeaee87d2be552843a830a0a20e252e76337b9596161"
 "checksum rustc-ap-rustc_cratesio_shim 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a78241b2ecb82ebb9221b4b7d37c024ff1f2e43f1b099f38a997f030fc7894b0"
-"checksum rustc-ap-rustc_cratesio_shim 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e8ea8fadc5d66c1527771816e83f7e7599543bd2e1583e279855370ab2f18e5"
+"checksum rustc-ap-rustc_cratesio_shim 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7ab5b83e209f3bcdb3c058a996d54b67db58eed5496bd114a781d9faa021aba7"
 "checksum rustc-ap-rustc_data_structures 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5529c3927f32b0b56d1f6449a34f2218dc2160c6a6dde0cf47954d83a9a45764"
-"checksum rustc-ap-rustc_data_structures 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "742ba74bc7d0f3ded56148329650f137fa5b90f7f0ecc4b4952150f32c66b147"
+"checksum rustc-ap-rustc_data_structures 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4bb330c149e9b133d4707718a7981d65ce4eb14f2d59cb487761aa922fefb206"
 "checksum rustc-ap-rustc_errors 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb1fef44a7d63f5d204c981adb26a14e85fe7ee5962050a4f664df6f425f9b48"
-"checksum rustc-ap-rustc_errors 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3714046c6f8c1c259822aefcca21b1862710a6cec24fd34c0796117f074c6769"
+"checksum rustc-ap-rustc_errors 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e19ae6a813d5cdd12b8b95cea71438bf8a5fa3505bea1e7d68d438a8ac5ae7b"
 "checksum rustc-ap-rustc_target 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a3939a9f7bf063536dd646894ca43b1378ec6a56ac5b2698cc6ba0b42bfadbdc"
-"checksum rustc-ap-rustc_target 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b982c4517c18080895b06149ce8aa8279fd013f629030bb7a179bfcff6d74ef2"
+"checksum rustc-ap-rustc_target 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "867d4a6bc1b62d373fc6ec72632d5cbd36f3cb1f4e51282d0c7b4e771b393031"
 "checksum rustc-ap-serialize 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "692169d0bac8a4547f9778039460799e162664477a1eaec15d31507705f8c736"
-"checksum rustc-ap-serialize 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "27c7700595bff1a64ddb6f593c69db3f6d66b76b059b26137236c7e21e36db70"
+"checksum rustc-ap-serialize 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e095f23598f115432ffef263201e030626f454d183cf425ef68fcca984f6594b"
 "checksum rustc-ap-syntax 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "22e93ee3817b007d56b5c5b151e6cd7c7063455a1facaf9e0ca01f9d9365b716"
-"checksum rustc-ap-syntax 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e6482d98c8be57d3cfe55dab744dd1a87f8462dc2ea0a8a4960f7bb1565be049"
+"checksum rustc-ap-syntax 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab8f97532dabc3713ac3e8d11a85f1a5b154486e79a0c2643d62078f0f948ce2"
 "checksum rustc-ap-syntax_pos 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe5d24a137d6e202cd6eb96cb74f8cb4a2b257c42b74dd624e136b4e19f0a47d"
-"checksum rustc-ap-syntax_pos 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "20af5e200b61a3e5ba4f58ed3cbd7593569faf8f0956d5233f4f27fee51b4c81"
+"checksum rustc-ap-syntax_pos 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e098adae207a4b8d470bc5e9565904cfe65dca799ba4c9efc872e7436eb5a67"
 "checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb"
 "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
 "checksum rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c6d5a683c6ba4ed37959097e88d71c9e8e26659a3cb5be8b389078e7ad45306"
index 08bdff364f84be0315e7e10e100bc717eb46dbc5..fa2440e27d06aba4f8125f480e619420a33e04be 100644 (file)
@@ -218,6 +218,12 @@ fn run(v: &[StepDescription], builder: &Builder, paths: &[PathBuf]) {
             }
         } else {
             for path in paths {
+                // strip CurDir prefix if present
+                let path = match path.strip_prefix(".") {
+                    Ok(p) => p,
+                    Err(_) => path,
+                };
+
                 let mut attempted_run = false;
                 for (desc, should_run) in v.iter().zip(&should_runs) {
                     if let Some(suite) = should_run.is_suite_path(path) {
index cbb42a04bdd52a838f2a3433f396193ee6e394c8..4fd6c81e5978682ec19ea71b65387362bfe3cabd 100644 (file)
@@ -44,7 +44,7 @@ pub fn pkgname(builder: &Builder, component: &str) -> String {
     } else if component == "rustfmt" {
         format!("{}-{}", component, builder.rustfmt_package_vers())
     } else if component == "llvm-tools" {
-        format!("{}-{}", component, builder.llvm_tools_vers())
+        format!("{}-{}", component, builder.llvm_tools_package_vers())
     } else {
         assert!(component.starts_with("rust"));
         format!("{}-{}", component, builder.rust_package_vers())
@@ -1303,6 +1303,7 @@ fn run(self, builder: &Builder) {
         let cargo_installer = builder.ensure(Cargo { stage, target });
         let rustfmt_installer = builder.ensure(Rustfmt { stage, target });
         let rls_installer = builder.ensure(Rls { stage, target });
+        let llvm_tools_installer = builder.ensure(LlvmTools { stage, target });
         let mingw_installer = builder.ensure(Mingw { host: target });
         let analysis_installer = builder.ensure(Analysis {
             compiler: builder.compiler(stage, self.host),
@@ -1340,6 +1341,7 @@ fn run(self, builder: &Builder) {
         tarballs.push(cargo_installer);
         tarballs.extend(rls_installer.clone());
         tarballs.extend(rustfmt_installer.clone());
+        tarballs.extend(llvm_tools_installer.clone());
         tarballs.push(analysis_installer);
         tarballs.push(std_installer);
         if builder.config.docs {
@@ -1740,7 +1742,7 @@ fn run(self, builder: &Builder) {
         cmd.arg(builder.package_vers(&builder.release_num("cargo")));
         cmd.arg(builder.package_vers(&builder.release_num("rls")));
         cmd.arg(builder.package_vers(&builder.release_num("rustfmt")));
-        cmd.arg(builder.llvm_tools_vers());
+        cmd.arg(builder.llvm_tools_package_vers());
         cmd.arg(addr);
 
         builder.create_dir(&distdir(builder));
@@ -1755,7 +1757,6 @@ fn run(self, builder: &Builder) {
 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
 pub struct LlvmTools {
     pub stage: u32,
-    pub compiler: Compiler,
     pub target: Interned<String>,
 }
 
@@ -1770,19 +1771,16 @@ fn should_run(run: ShouldRun) -> ShouldRun {
     fn make_run(run: RunConfig) {
         run.builder.ensure(LlvmTools {
             stage: run.builder.top_stage,
-            compiler: run.builder.compiler(run.builder.top_stage, run.target),
             target: run.target,
         });
     }
 
     fn run(self, builder: &Builder) -> Option<PathBuf> {
-        let compiler = self.compiler;
-        let host = compiler.host;
-
         let stage = self.stage;
+        let target = self.target;
         assert!(builder.config.extended);
 
-        builder.info(&format!("Dist LlvmTools stage{} ({})", stage, host));
+        builder.info(&format!("Dist LlvmTools stage{} ({})", stage, target));
         let src = builder.src.join("src/llvm");
         let name = pkgname(builder, "llvm-tools");
 
@@ -1794,9 +1792,9 @@ fn run(self, builder: &Builder) -> Option<PathBuf> {
         // Prepare the image directory
         for tool in LLVM_TOOLS {
             let exe = builder
-                .llvm_out(host)
+                .llvm_out(target)
                 .join("bin")
-                .join(exe(tool, &compiler.host));
+                .join(exe(tool, &target));
             builder.install(&exe, &image.join("bin"), 0o755);
         }
 
@@ -1806,6 +1804,7 @@ fn run(self, builder: &Builder) -> Option<PathBuf> {
         builder.create_dir(&overlay);
         builder.install(&src.join("README.txt"), &overlay, 0o644);
         builder.install(&src.join("LICENSE.TXT"), &overlay, 0o644);
+        builder.create(&overlay.join("version"), &builder.llvm_tools_vers());
 
         // Generate the installer tarball
         let mut cmd = rust_installer(builder);
@@ -1817,12 +1816,12 @@ fn run(self, builder: &Builder) -> Option<PathBuf> {
             .arg("--work-dir").arg(&tmpdir(builder))
             .arg("--output-dir").arg(&distdir(builder))
             .arg("--non-installed-overlay").arg(&overlay)
-            .arg(format!("--package-name={}-{}", name, host))
+            .arg(format!("--package-name={}-{}", name, target))
             .arg("--legacy-manifest-dirs=rustlib,cargo")
             .arg("--component-name=llvm-tools");
 
 
         builder.run(&mut cmd);
-        Some(distdir(builder).join(format!("{}-{}.tar.gz", name, host)))
+        Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
     }
 }
index ae37d67e5d7bc8310ccd9af5598be8ce70d00902..b5d450b88392d0d8bd1c575f72bd4fe0cbc5f5bd 100644 (file)
@@ -973,24 +973,11 @@ fn rustfmt_package_vers(&self) -> String {
         self.package_vers(&self.release_num("rustfmt"))
     }
 
-    fn llvm_tools_vers(&self) -> String {
-        // japaric: should we use LLVM version here?
-        // let stdout = build_helper::output(
-        //     Command::new(self.llvm_out(self.config.build).join("build/bin/llvm-size"))
-        //         .arg("--version"),
-        // );
-
-        // for line in stdout.lines() {
-        //     if line.contains("LLVM version") {
-        //         if let Some(vers) = line.split_whitespace().nth(2) {
-        //             return vers.to_string();
-        //         }
-        //     }
-        // }
-
-        // panic!("The output of $LLVM_TOOL has changed; \
-        //         please fix `bootstrap::Build.llvm_tools_vers`");
+    fn llvm_tools_package_vers(&self) -> String {
+        self.package_vers(&self.rust_version())
+    }
 
+    fn llvm_tools_vers(&self) -> String {
         self.rust_version()
     }
 
index d2fd798723dabbf0c6abf809eb50f56b32c11c18..90688b1c0e181e095aa73c6ff814879e1fcf8f53 100644 (file)
@@ -1074,6 +1074,12 @@ fn run(self, builder: &Builder) {
         // Get test-args by striping suite path
         let mut test_args: Vec<&str> = paths
             .iter()
+            .map(|p| {
+                match p.strip_prefix(".") {
+                    Ok(path) => path,
+                    Err(_) => p,
+                }
+            })
             .filter(|p| p.starts_with(suite_path) && p.is_file())
             .map(|p| p.strip_prefix(suite_path).unwrap().to_str().unwrap())
             .collect();
index cb233cc84cbed8fd95ddbce645dcabfe35a0cd45..7639537fc553539055e976c897388d278221fce1 100644 (file)
@@ -305,3 +305,27 @@ environment that has no network access.
 compiles, then the test will fail. However please note that code failing
 with the current Rust release may work in a future release, as new features
 are added.
+
+## Syntax reference
+
+The *exact* syntax for code blocks, including the edge cases, can be found
+in the [Fenced Code Blocks](https://spec.commonmark.org/0.28/#fenced-code-blocks)
+section of the CommonMark specification.
+
+Rustdoc also accepts *indented* code blocks as an alternative to fenced
+code blocks: instead of surrounding your code with three backticks, you
+can indent each line by four or more spaces.
+
+``````markdown
+    let foo = "foo";
+    assert_eq!(foo, "foo");
+``````
+
+These, too, are documented in the CommonMark specification, in the
+[Indented Code Blocks](https://spec.commonmark.org/0.28/#indented-code-blocks)
+section.
+
+However, it's preferable to use fenced code blocks over indented code blocks.
+Not only are fenced code blocks considered more idiomatic for Rust code,
+but there is no way to use directives such as `ignore` or `should_panic` with
+indented code blocks.
diff --git a/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md b/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md
new file mode 100644 (file)
index 0000000..46b8437
--- /dev/null
@@ -0,0 +1,28 @@
+# `irrefutable_let_patterns`
+
+The tracking issue for this feature is: [#44495]
+
+[#44495]: https://github.com/rust-lang/rust/issues/44495
+
+------------------------
+
+This feature changes the way that "irrefutable patterns" are handled
+in the `if let` and `while let` forms. An *irrefutable pattern* is one
+that cannot fail to match -- for example, the `_` pattern matches any
+value, and hence it is "irrefutable". Without this feature, using an
+irrefutable pattern in an `if let` gives a hard error (since often
+this indicates programmer error). But when the feature is enabled, the
+error becomes a lint (since in some cases irrefutable patterns are
+expected). This means you can use `#[allow]` to silence the lint:
+
+```rust
+#![feature(irrefutable_let_patterns)]
+
+#[allow(irrefutable_let_patterns)]
+fn main() {
+    // These two examples used to be errors, but now they
+    // trigger a lint (that is allowed):
+    if let _ = 5 {}
+    while let _ = 5 { break; }
+}
+```
index b5739e1a825538ceffa016bd3f2a550d5e39ae28..752a6c966d51a35bcd4de701b6055f640255d4f9 100644 (file)
@@ -1693,7 +1693,10 @@ fn hash<H: hash::Hasher>(&self, state: &mut H) {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
+#[rustc_on_unimplemented(
+    message="vector indices are of type `usize` or ranges of `usize`",
+    label="vector indices are of type `usize` or ranges of `usize`",
+)]
 impl<T, I> Index<I> for Vec<T>
 where
     I: ::core::slice::SliceIndex<[T]>,
@@ -1707,7 +1710,10 @@ fn index(&self, index: I) -> &Self::Output {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
+#[rustc_on_unimplemented(
+    message="vector indices are of type `usize` or ranges of `usize`",
+    label="vector indices are of type `usize` or ranges of `usize`",
+)]
 impl<T, I> IndexMut<I> for Vec<T>
 where
     I: ::core::slice::SliceIndex<[T]>,
index 13e838773a5875faf0a0da4117644d9f45776c94..3626a266ad5d3f0d86cd059ede2c21fbae92c816 100644 (file)
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(alias = "==")]
 #[doc(alias = "!=")]
-#[rustc_on_unimplemented = "can't compare `{Self}` with `{Rhs}`"]
+#[rustc_on_unimplemented(
+    message="can't compare `{Self}` with `{Rhs}`",
+    label="no implementation for `{Self} == {Rhs}`",
+)]
 pub trait PartialEq<Rhs: ?Sized = Self> {
     /// This method tests for `self` and `other` values to be equal, and is used
     /// by `==`.
@@ -611,7 +614,10 @@ fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
 #[doc(alias = "<")]
 #[doc(alias = "<=")]
 #[doc(alias = ">=")]
-#[rustc_on_unimplemented = "can't compare `{Self}` with `{Rhs}`"]
+#[rustc_on_unimplemented(
+    message="can't compare `{Self}` with `{Rhs}`",
+    label="no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`",
+)]
 pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
     /// This method returns an ordering between `self` and `other` values if one exists.
     ///
index 3d2ce9e6b104bc9aae32559816e10a81eb9bf9bb..4b2c1aa551e994ad7470de7480abea31edb20e42 100644 (file)
 /// assert_eq!(c.0, vec![0, 1, 2, 3, 4]);
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented="a collection of type `{Self}` cannot be \
-                          built from an iterator over elements of type `{A}`"]
+#[rustc_on_unimplemented(
+    message="a collection of type `{Self}` cannot be built from an iterator \
+             over elements of type `{A}`",
+    label="a collection of type `{Self}` cannot be built from `std::iter::Iterator<Item={A}>`",
+)]
 pub trait FromIterator<A>: Sized {
     /// Creates a value from an iterator.
     ///
index 3d3f63ecf37d57e1c5eb46ca640ef449ef336ab2..5db5d88d4a5ff9bc2e3036ba5e9d1ecb46ed7c7b 100644 (file)
 /// [arc]: ../../std/sync/struct.Arc.html
 /// [ub]: ../../reference/behavior-considered-undefined.html
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
+#[rustc_on_unimplemented(
+    message="`{Self}` cannot be sent between threads safely",
+    label="`{Self}` cannot be sent between threads safely"
+)]
 pub unsafe auto trait Send {
     // empty.
 }
@@ -88,7 +91,12 @@ impl<T: ?Sized> !Send for *mut T { }
 /// [trait object]: ../../book/first-edition/trait-objects.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "sized"]
-#[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"]
+#[rustc_on_unimplemented(
+    message="the size for value values of type `{Self}` cannot be known at compilation time",
+    label="doesn't have a size known at compile-time",
+    note="to learn more, visit <https://doc.rust-lang.org/book/second-edition/\
+          ch19-04-advanced-types.html#dynamically-sized-types--sized>",
+)]
 #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
 pub trait Sized {
     // Empty.
index 31635ffa53c83b20ab7172bd2ea5480760bcbbf6..08bd9289ab48758559b14030151c36e343fbb078 100644 (file)
@@ -1119,6 +1119,12 @@ impl<'a, T: ?Sized + Unpin> PinMut<'a, T> {
     pub fn new(reference: &'a mut T) -> PinMut<'a, T> {
         PinMut { inner: reference }
     }
+
+    /// Get a mutable reference to the data inside of this `PinMut`.
+    #[unstable(feature = "pin", issue = "49150")]
+    pub fn get_mut(this: PinMut<'a, T>) -> &'a mut T {
+        this.inner
+    }
 }
 
 
@@ -1150,21 +1156,21 @@ pub fn reborrow<'b>(&'b mut self) -> PinMut<'b, T> {
     /// the data out of the mutable reference you receive when you call this
     /// function.
     #[unstable(feature = "pin", issue = "49150")]
-    pub unsafe fn get_mut(this: PinMut<'a, T>) -> &'a mut T {
+    pub unsafe fn get_mut_unchecked(this: PinMut<'a, T>) -> &'a mut T {
         this.inner
     }
 
     /// Construct a new pin by mapping the interior value.
     ///
-    /// For example, if you  wanted to get a `PinMut` of a field of something, you
-    /// could use this to get access to that field in one line of code.
+    /// For example, if you  wanted to get a `PinMut` of a field of something,
+    /// you could use this to get access to that field in one line of code.
     ///
     /// This function is unsafe. You must guarantee that the data you return
     /// will not move so long as the argument value does not move (for example,
     /// because it is one of the fields of that value), and also that you do
     /// not move out of the argument you receive to the interior function.
     #[unstable(feature = "pin", issue = "49150")]
-    pub unsafe fn map<U, F>(this: PinMut<'a, T>, f: F) -> PinMut<'a, U> where
+    pub unsafe fn map_unchecked<U, F>(this: PinMut<'a, T>, f: F) -> PinMut<'a, U> where
         F: FnOnce(&mut T) -> &mut U
     {
         PinMut { inner: f(this.inner) }
index 0a0e92a91800614a75608bd7099eb2e4fe79ab54..1ac80ecc96ffeb775cd6fc3ffc2d52f018aacbb2 100644 (file)
 /// assert_eq!(nucleotide_count[Nucleotide::T], 12);
 /// ```
 #[lang = "index"]
-#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
+#[rustc_on_unimplemented(
+    message="the type `{Self}` cannot be indexed by `{Idx}`",
+    label="`{Self}` cannot be indexed by `{Idx}`",
+)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(alias = "]")]
 #[doc(alias = "[")]
@@ -147,7 +150,10 @@ pub trait Index<Idx: ?Sized> {
 /// balance[Side::Left] = Weight::Kilogram(3.0);
 /// ```
 #[lang = "index_mut"]
-#[rustc_on_unimplemented = "the type `{Self}` cannot be mutably indexed by `{Idx}`"]
+#[rustc_on_unimplemented(
+    message="the type `{Self}` cannot be mutably indexed by `{Idx}`",
+    label="`{Self}` cannot be mutably indexed by `{Idx}`",
+)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(alias = "[")]
 #[doc(alias = "]")]
index 1e615042a6d88361257d1868fc05a5f4d2f631ab..20bc173f7e1548043c5c28bebfb57649e5518472 100644 (file)
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use iter::{FromIterator, FusedIterator, TrustedLen};
-use {mem, ops};
+use {hint, mem, ops};
 use mem::PinMut;
 
 // Note that this is not a lang item per se, but it has a hidden dependency on
@@ -275,7 +275,7 @@ pub fn as_mut(&mut self) -> Option<&mut T> {
     #[unstable(feature = "pin", issue = "49150")]
     pub fn as_pin_mut<'a>(self: PinMut<'a, Self>) -> Option<PinMut<'a, T>> {
         unsafe {
-            PinMut::get_mut(self).as_mut().map(|x| PinMut::new_unchecked(x))
+            PinMut::get_mut_unchecked(self).as_mut().map(|x| PinMut::new_unchecked(x))
         }
     }
 
@@ -784,7 +784,7 @@ pub fn get_or_insert(&mut self, v: T) -> &mut T {
 
         match *self {
             Some(ref mut v) => v,
-            _ => unreachable!(),
+            None => unsafe { hint::unreachable_unchecked() },
         }
     }
 
@@ -817,7 +817,7 @@ pub fn get_or_insert_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
 
         match *self {
             Some(ref mut v) => v,
-            _ => unreachable!(),
+            None => unsafe { hint::unreachable_unchecked() },
         }
     }
 
index c9d0bc1405fc01dcb17fcf6432590a0f32864786..4cd822aa9d0b969689318d6e08d2e850beea3ac3 100644 (file)
@@ -85,9 +85,6 @@ fn expand<'cx>(&self, cx: &'cx mut ExtCtxt,
                    _: ::syntax_pos::Span,
                    stream: tokenstream::TokenStream)
                    -> tokenstream::TokenStream {
-        let mut info = cx.current_expansion.mark.expn_info().unwrap();
-        info.callee.allow_internal_unstable = true;
-        cx.current_expansion.mark.set_expn_info(info);
         ::__internal::set_sess(cx, || TokenStream(stream).quote().0)
     }
 }
index 20e4b1343c1b8d247bb1af226725774a9d8c51b0..f52d201abecb90a6bee88466146fefe33650519e 100644 (file)
@@ -335,7 +335,7 @@ fn expr(&mut self, expr: &hir::Expr, pred: CFGIndex) -> CFGIndex {
                 self.add_unreachable_node()
             }
 
-            hir::ExprAgain(destination) => {
+            hir::ExprContinue(destination) => {
                 let (target_scope, cont_dest) =
                     self.find_scope_edge(expr, destination, ScopeCfKind::Continue);
                 let a = self.add_ast_node(expr.hir_id.local_id, &[pred]);
index 1435957a5c1426f726beba2be389c6499a361010..5fecf2b15359fcce888cbae08506e00797d3f9ae 100644 (file)
@@ -2131,5 +2131,10 @@ trait Foo { }
     E0657, // `impl Trait` can only capture lifetimes bound at the fn level
     E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
     E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
+
     E0697, // closures cannot be static
+
+    E0707, // multiple elided lifetimes used in arguments of `async fn`
+    E0708, // `async` non-`move` closures with arguments are not currently supported
+    E0709, // multiple different lifetimes used in arguments of `async fn`
 }
index 12ccb329e06ff2cd541b0ae6b3c6c325f4cde16f..2a351d99841ff1a5acd4faab6a9e3fd21a4b3ca5 100644 (file)
@@ -41,7 +41,6 @@
 //! This order consistency is required in a few places in rustc, for
 //! example generator inference, and possibly also HIR borrowck.
 
-use rustc_target::spec::abi::Abi;
 use syntax::ast::{NodeId, CRATE_NODE_ID, Ident, Name, Attribute};
 use syntax_pos::Span;
 use hir::*;
@@ -54,8 +53,8 @@
 
 #[derive(Copy, Clone, PartialEq, Eq)]
 pub enum FnKind<'a> {
-    /// fn foo() or extern "Abi" fn foo()
-    ItemFn(Name, &'a Generics, Unsafety, Constness, Abi, &'a Visibility, &'a [Attribute]),
+    /// #[xxx] pub async/const/extern "Abi" fn foo()
+    ItemFn(Name, &'a Generics, FnHeader, &'a Visibility, &'a [Attribute]),
 
     /// fn foo(&self)
     Method(Name, &'a MethodSig, Option<&'a Visibility>, &'a [Attribute]),
@@ -314,8 +313,8 @@ fn visit_impl_item_ref(&mut self, ii: &'v ImplItemRef) {
     fn visit_trait_ref(&mut self, t: &'v TraitRef) {
         walk_trait_ref(self, t)
     }
-    fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) {
-        walk_ty_param_bound(self, bounds)
+    fn visit_param_bound(&mut self, bounds: &'v GenericBound) {
+        walk_param_bound(self, bounds)
     }
     fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: TraitBoundModifier) {
         walk_poly_trait_ref(self, t, m)
@@ -344,6 +343,12 @@ fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics, item_id: NodeId) {
     fn visit_label(&mut self, label: &'v Label) {
         walk_label(self, label)
     }
+    fn visit_generic_arg(&mut self, generic_arg: &'v GenericArg) {
+        match generic_arg {
+            GenericArg::Lifetime(lt) => self.visit_lifetime(lt),
+            GenericArg::Type(ty) => self.visit_ty(ty),
+        }
+    }
     fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
         walk_lifetime(self, lifetime)
     }
@@ -356,8 +361,8 @@ fn visit_path(&mut self, path: &'v Path, _id: NodeId) {
     fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
         walk_path_segment(self, path_span, path_segment)
     }
-    fn visit_path_parameters(&mut self, path_span: Span, path_parameters: &'v PathParameters) {
-        walk_path_parameters(self, path_span, path_parameters)
+    fn visit_generic_args(&mut self, path_span: Span, generic_args: &'v GenericArgs) {
+        walk_generic_args(self, path_span, generic_args)
     }
     fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding) {
         walk_assoc_type_binding(self, type_binding)
@@ -427,10 +432,10 @@ pub fn walk_label<'v, V: Visitor<'v>>(visitor: &mut V, label: &'v Label) {
 pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) {
     visitor.visit_id(lifetime.id);
     match lifetime.name {
-        LifetimeName::Name(name) => {
+        LifetimeName::Param(ParamName::Plain(name)) => {
             visitor.visit_name(lifetime.span, name);
         }
-        LifetimeName::Fresh(_) |
+        LifetimeName::Param(ParamName::Fresh(_)) |
         LifetimeName::Static |
         LifetimeName::Implicit |
         LifetimeName::Underscore => {}
@@ -473,12 +478,10 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
             visitor.visit_ty(typ);
             visitor.visit_nested_body(body);
         }
-        ItemFn(ref declaration, unsafety, constness, abi, ref generics, body_id) => {
+        ItemFn(ref declaration, header, ref generics, body_id) => {
             visitor.visit_fn(FnKind::ItemFn(item.name,
                                             generics,
-                                            unsafety,
-                                            constness,
-                                            abi,
+                                            header,
                                             &item.vis,
                                             &item.attrs),
                              declaration,
@@ -505,7 +508,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
         ItemExistential(ExistTy {ref generics, ref bounds, impl_trait_fn}) => {
             visitor.visit_id(item.id);
             walk_generics(visitor, generics);
-            walk_list!(visitor, visit_ty_param_bound, bounds);
+            walk_list!(visitor, visit_param_bound, bounds);
             if let Some(impl_trait_fn) = impl_trait_fn {
                 visitor.visit_def_mention(Def::Fn(impl_trait_fn))
             }
@@ -531,13 +534,13 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
         ItemTrait(.., ref generics, ref bounds, ref trait_item_refs) => {
             visitor.visit_id(item.id);
             visitor.visit_generics(generics);
-            walk_list!(visitor, visit_ty_param_bound, bounds);
+            walk_list!(visitor, visit_param_bound, bounds);
             walk_list!(visitor, visit_trait_item_ref, trait_item_refs);
         }
         ItemTraitAlias(ref generics, ref bounds) => {
             visitor.visit_id(item.id);
             visitor.visit_generics(generics);
-            walk_list!(visitor, visit_ty_param_bound, bounds);
+            walk_list!(visitor, visit_param_bound, bounds);
         }
     }
     walk_list!(visitor, visit_attribute, &item.attrs);
@@ -642,17 +645,16 @@ pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
                                              path_span: Span,
                                              segment: &'v PathSegment) {
     visitor.visit_name(path_span, segment.name);
-    if let Some(ref parameters) = segment.parameters {
-        visitor.visit_path_parameters(path_span, parameters);
+    if let Some(ref args) = segment.args {
+        visitor.visit_generic_args(path_span, args);
     }
 }
 
-pub fn walk_path_parameters<'v, V: Visitor<'v>>(visitor: &mut V,
-                                                _path_span: Span,
-                                                path_parameters: &'v PathParameters) {
-    walk_list!(visitor, visit_lifetime, &path_parameters.lifetimes);
-    walk_list!(visitor, visit_ty, &path_parameters.types);
-    walk_list!(visitor, visit_assoc_type_binding, &path_parameters.bindings);
+pub fn walk_generic_args<'v, V: Visitor<'v>>(visitor: &mut V,
+                                             _path_span: Span,
+                                             generic_args: &'v GenericArgs) {
+    walk_list!(visitor, visit_generic_arg, &generic_args.args);
+    walk_list!(visitor, visit_assoc_type_binding, &generic_args.bindings);
 }
 
 pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V,
@@ -726,40 +728,27 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v
     walk_list!(visitor, visit_attribute, &foreign_item.attrs);
 }
 
-pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v TyParamBound) {
+pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericBound) {
     match *bound {
-        TraitTyParamBound(ref typ, modifier) => {
+        GenericBound::Trait(ref typ, modifier) => {
             visitor.visit_poly_trait_ref(typ, modifier);
         }
-        RegionTyParamBound(ref lifetime) => {
-            visitor.visit_lifetime(lifetime);
-        }
+        GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
     }
 }
 
 pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v GenericParam) {
-    match *param {
-        GenericParam::Lifetime(ref ld) => {
-            visitor.visit_id(ld.lifetime.id);
-            match ld.lifetime.name {
-                LifetimeName::Name(name) => {
-                    visitor.visit_name(ld.lifetime.span, name);
-                }
-                LifetimeName::Fresh(_) |
-                LifetimeName::Static |
-                LifetimeName::Implicit |
-                LifetimeName::Underscore => {}
-            }
-            walk_list!(visitor, visit_lifetime, &ld.bounds);
-        }
-        GenericParam::Type(ref ty_param) => {
-            visitor.visit_id(ty_param.id);
-            visitor.visit_name(ty_param.span, ty_param.name);
-            walk_list!(visitor, visit_ty_param_bound, &ty_param.bounds);
-            walk_list!(visitor, visit_ty, &ty_param.default);
-            walk_list!(visitor, visit_attribute, ty_param.attrs.iter());
-        }
+    visitor.visit_id(param.id);
+    walk_list!(visitor, visit_attribute, &param.attrs);
+    match param.name {
+        ParamName::Plain(name) => visitor.visit_name(param.span, name),
+        ParamName::Fresh(_) => {}
+    }
+    match param.kind {
+        GenericParamKind::Lifetime { .. } => {}
+        GenericParamKind::Type { ref default, .. } => walk_list!(visitor, visit_ty, default),
     }
+    walk_list!(visitor, visit_param_bound, &param.bounds);
 }
 
 pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) {
@@ -778,14 +767,14 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>(
                                                             ref bound_generic_params,
                                                             ..}) => {
             visitor.visit_ty(bounded_ty);
-            walk_list!(visitor, visit_ty_param_bound, bounds);
+            walk_list!(visitor, visit_param_bound, bounds);
             walk_list!(visitor, visit_generic_param, bound_generic_params);
         }
         &WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime,
                                                               ref bounds,
                                                               ..}) => {
             visitor.visit_lifetime(lifetime);
-            walk_list!(visitor, visit_lifetime, bounds);
+            walk_list!(visitor, visit_param_bound, bounds);
         }
         &WherePredicate::EqPredicate(WhereEqPredicate{id,
                                                       ref lhs_ty,
@@ -862,7 +851,7 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
         }
         TraitItemKind::Type(ref bounds, ref default) => {
             visitor.visit_id(trait_item.id);
-            walk_list!(visitor, visit_ty_param_bound, bounds);
+            walk_list!(visitor, visit_param_bound, bounds);
             walk_list!(visitor, visit_ty, default);
         }
     }
@@ -1079,7 +1068,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
             }
             walk_list!(visitor, visit_expr, opt_expr);
         }
-        ExprAgain(ref destination) => {
+        ExprContinue(ref destination) => {
             if let Some(ref label) = destination.label {
                 visitor.visit_label(label);
                 match destination.target_id {
index dd12edb73027a39e72cb727e362207c0cb128754..484c41b3a79965c231f57f8d709fe9aaccb9ae25 100644 (file)
 //! in the HIR, especially for multiple identifiers.
 
 use dep_graph::DepGraph;
-use hir;
+use hir::{self, ParamName};
 use hir::HirVec;
 use hir::map::{DefKey, DefPathData, Definitions};
 use hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX};
 use hir::def::{Def, PathResolution, PerNS};
+use hir::GenericArg;
 use lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES};
 use middle::cstore::CrateStore;
 use rustc_data_structures::indexed_vec::IndexVec;
@@ -58,6 +59,7 @@
 use std::iter;
 use std::mem;
 use syntax::attr;
+use syntax::ast;
 use syntax::ast::*;
 use syntax::errors;
 use syntax::ext::hygiene::{Mark, SyntaxContext};
@@ -114,7 +116,7 @@ pub struct LoweringContext<'a> {
     // When traversing a signature such as `fn foo(x: impl Trait)`,
     // we record `impl Trait` as a new type parameter, then later
     // add it on to `foo`s generics.
-    in_band_ty_params: Vec<hir::TyParam>,
+    in_band_ty_params: Vec<hir::GenericParam>,
 
     // Used to create lifetime definitions from in-band lifetime usages.
     // e.g. `fn foo(x: &'x u8) -> &'x u8` to `fn foo<'x>(x: &'x u8) -> &'x u8`
@@ -123,7 +125,7 @@ pub struct LoweringContext<'a> {
     // (i.e. it doesn't appear in the in_scope_lifetimes list), it is added
     // to this list. The results of this list are then added to the list of
     // lifetime definitions in the corresponding impl or function generics.
-    lifetimes_to_define: Vec<(Span, hir::LifetimeName)>,
+    lifetimes_to_define: Vec<(Span, ParamName)>,
 
     // Whether or not in-band lifetimes are being collected. This is used to
     // indicate whether or not we're in a place where new lifetimes will result
@@ -166,6 +168,7 @@ fn resolve_str_path(
         span: Span,
         crate_root: Option<&str>,
         components: &[&str],
+        params: Option<P<hir::GenericArgs>>,
         is_value: bool,
     ) -> hir::Path;
 }
@@ -322,7 +325,10 @@ fn visit_item(&mut self, item: &'lcx Item) {
                         let count = generics
                             .params
                             .iter()
-                            .filter(|param| param.is_lifetime_param())
+                            .filter(|param| match param.kind {
+                                ast::GenericParamKind::Lifetime { .. } => true,
+                                _ => false,
+                            })
                             .count();
                         self.lctx.type_def_lifetime_params.insert(def_id, count);
                     }
@@ -374,25 +380,24 @@ fn visit_item(&mut self, item: &'lcx Item) {
                 });
 
                 if item_lowered {
-                    let item_lifetimes = match self.lctx.items.get(&item.id).unwrap().node {
+                    let item_generics = match self.lctx.items.get(&item.id).unwrap().node {
                         hir::Item_::ItemImpl(_, _, _, ref generics, ..)
                         | hir::Item_::ItemTrait(_, _, ref generics, ..) => {
-                            generics.lifetimes().cloned().collect::<Vec<_>>()
+                            generics.params.clone()
                         }
-                        _ => Vec::new(),
+                        _ => HirVec::new(),
                     };
 
-                    self.lctx
-                        .with_parent_impl_lifetime_defs(&item_lifetimes, |this| {
-                            let this = &mut ItemLowerer { lctx: this };
-                            if let ItemKind::Impl(_, _, _, _, ref opt_trait_ref, _, _) = item.node {
-                                this.with_trait_impl_ref(opt_trait_ref, |this| {
-                                    visit::walk_item(this, item)
-                                });
-                            } else {
-                                visit::walk_item(this, item);
-                            }
-                        });
+                    self.lctx.with_parent_impl_lifetime_defs(&item_generics, |this| {
+                        let this = &mut ItemLowerer { lctx: this };
+                        if let ItemKind::Impl(_, _, _, _, ref opt_trait_ref, _, _) = item.node {
+                            this.with_trait_impl_ref(opt_trait_ref, |this| {
+                                visit::walk_item(this, item)
+                            });
+                        } else {
+                            visit::walk_item(this, item);
+                        }
+                    });
                 }
             }
 
@@ -445,7 +450,7 @@ fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
         }
     }
 
-    fn allocate_hir_id_counter<T: Debug>(&mut self, owner: NodeId, debug: &T) {
+    fn allocate_hir_id_counter<T: Debug>(&mut self, owner: NodeId, debug: &T) -> LoweredNodeId {
         if self.item_local_id_counters.insert(owner, 0).is_some() {
             bug!(
                 "Tried to allocate item_local_id_counter for {:?} twice",
@@ -453,7 +458,7 @@ fn allocate_hir_id_counter<T: Debug>(&mut self, owner: NodeId, debug: &T) {
             );
         }
         // Always allocate the first HirId for the owner itself
-        self.lower_node_id_with_owner(owner, owner);
+        self.lower_node_id_with_owner(owner, owner)
     }
 
     fn lower_node_id_generic<F>(&mut self, ast_node_id: NodeId, alloc_hir_id: F) -> LoweredNodeId
@@ -497,7 +502,7 @@ fn with_hir_id_owner<F, T>(&mut self, owner: NodeId, f: F) -> T
     {
         let counter = self.item_local_id_counters
             .insert(owner, HIR_ID_COUNTER_LOCKED)
-            .unwrap();
+            .unwrap_or_else(|| panic!("No item_local_id_counters entry for {:?}", owner));
         let def_index = self.resolver.definitions().opt_def_index(owner).unwrap();
         self.current_hir_id_owner.push((def_index, counter));
         let ret = f(self);
@@ -607,13 +612,11 @@ fn allow_internal_unstable(&self, reason: CompilerDesugaringKind, span: Span) ->
         let mark = Mark::fresh(Mark::root());
         mark.set_expn_info(codemap::ExpnInfo {
             call_site: span,
-            callee: codemap::NameAndSpan {
-                format: codemap::CompilerDesugaring(reason),
-                span: Some(span),
-                allow_internal_unstable: true,
-                allow_internal_unsafe: false,
-                edition: codemap::hygiene::default_edition(),
-            },
+            def_site: Some(span),
+            format: codemap::CompilerDesugaring(reason),
+            allow_internal_unstable: true,
+            allow_internal_unsafe: false,
+            edition: codemap::hygiene::default_edition(),
         });
         span.with_ctxt(SyntaxContext::empty().apply_mark(mark))
     }
@@ -674,41 +677,31 @@ fn collect_in_band_defs<T, F>(
                 // that collisions are ok here and this shouldn't
                 // really show up for end-user.
                 let str_name = match hir_name {
-                    hir::LifetimeName::Name(n) => n.as_str(),
-                    hir::LifetimeName::Fresh(_) => keywords::UnderscoreLifetime.name().as_str(),
-                    hir::LifetimeName::Implicit
-                    | hir::LifetimeName::Underscore
-                    | hir::LifetimeName::Static => {
-                        span_bug!(span, "unexpected in-band lifetime name: {:?}", hir_name)
-                    }
+                    ParamName::Plain(name) => name.as_str(),
+                    ParamName::Fresh(_) => keywords::UnderscoreLifetime.name().as_str(),
                 };
 
                 // Add a definition for the in-band lifetime def
                 self.resolver.definitions().create_def_with_parent(
                     parent_id.index,
                     def_node_id,
-                    DefPathData::LifetimeDef(str_name.as_interned_str()),
+                    DefPathData::LifetimeParam(str_name.as_interned_str()),
                     DefIndexAddressSpace::High,
                     Mark::root(),
                     span,
                 );
 
-                hir::GenericParam::Lifetime(hir::LifetimeDef {
-                    lifetime: hir::Lifetime {
-                        id: def_node_id,
-                        span,
-                        name: hir_name,
-                    },
-                    bounds: Vec::new().into(),
+                hir::GenericParam {
+                    id: def_node_id,
+                    name: hir_name,
+                    attrs: hir_vec![],
+                    bounds: hir_vec![],
+                    span,
                     pure_wrt_drop: false,
-                    in_band: true,
-                })
+                    kind: hir::GenericParamKind::Lifetime { in_band: true }
+                }
             })
-            .chain(
-                in_band_ty_params
-                    .into_iter()
-                    .map(|tp| hir::GenericParam::Type(tp)),
-            )
+            .chain(in_band_ty_params.into_iter())
             .collect();
 
         (params, res)
@@ -727,12 +720,9 @@ fn maybe_collect_in_band_lifetime(&mut self, span: Span, name: Name) {
             return;
         }
 
-        let hir_name = hir::LifetimeName::Name(name);
+        let hir_name = ParamName::Plain(name);
 
-        if self.lifetimes_to_define
-            .iter()
-            .any(|(_, lt_name)| *lt_name == hir_name)
-        {
+        if self.lifetimes_to_define.iter().any(|(_, lt_name)| *lt_name == hir_name) {
             return;
         }
 
@@ -741,28 +731,27 @@ fn maybe_collect_in_band_lifetime(&mut self, span: Span, name: Name) {
 
     /// When we have either an elided or `'_` lifetime in an impl
     /// header, we convert it to
-    fn collect_fresh_in_band_lifetime(&mut self, span: Span) -> hir::LifetimeName {
+    fn collect_fresh_in_band_lifetime(&mut self, span: Span) -> ParamName {
         assert!(self.is_collecting_in_band_lifetimes);
         let index = self.lifetimes_to_define.len();
-        let hir_name = hir::LifetimeName::Fresh(index);
+        let hir_name = ParamName::Fresh(index);
         self.lifetimes_to_define.push((span, hir_name));
         hir_name
     }
 
-    // Evaluates `f` with the lifetimes in `lt_defs` in-scope.
+    // Evaluates `f` with the lifetimes in `params` in-scope.
     // This is used to track which lifetimes have already been defined, and
     // which are new in-band lifetimes that need to have a definition created
     // for them.
-    fn with_in_scope_lifetime_defs<'l, T, F>(
-        &mut self,
-        lt_defs: impl Iterator<Item = &'l LifetimeDef>,
-        f: F,
-    ) -> T
+    fn with_in_scope_lifetime_defs<T, F>(&mut self, params: &Vec<GenericParam>, f: F) -> T
     where
         F: FnOnce(&mut LoweringContext) -> T,
     {
         let old_len = self.in_scope_lifetimes.len();
-        let lt_def_names = lt_defs.map(|lt_def| lt_def.lifetime.ident.name);
+        let lt_def_names = params.iter().filter_map(|param| match param.kind {
+            GenericParamKind::Lifetime { .. } => Some(param.ident.name),
+            _ => None,
+        });
         self.in_scope_lifetimes.extend(lt_def_names);
 
         let res = f(self);
@@ -771,17 +760,22 @@ fn with_in_scope_lifetime_defs<'l, T, F>(
         res
     }
 
-    // Same as the method above, but accepts `hir::LifetimeDef`s
-    // instead of `ast::LifetimeDef`s.
+    // Same as the method above, but accepts `hir::GenericParam`s
+    // instead of `ast::GenericParam`s.
     // This should only be used with generics that have already had their
     // in-band lifetimes added. In practice, this means that this function is
     // only used when lowering a child item of a trait or impl.
-    fn with_parent_impl_lifetime_defs<T, F>(&mut self, lt_defs: &[hir::LifetimeDef], f: F) -> T
-    where
+    fn with_parent_impl_lifetime_defs<T, F>(&mut self,
+        params: &HirVec<hir::GenericParam>,
+        f: F
+    ) -> T where
         F: FnOnce(&mut LoweringContext) -> T,
     {
         let old_len = self.in_scope_lifetimes.len();
-        let lt_def_names = lt_defs.iter().map(|lt_def| lt_def.lifetime.name.name());
+        let lt_def_names = params.iter().filter_map(|param| match param.kind {
+            hir::GenericParamKind::Lifetime { .. } => Some(param.name.name()),
+            _ => None,
+        });
         self.in_scope_lifetimes.extend(lt_def_names);
 
         let res = f(self);
@@ -807,10 +801,7 @@ fn add_in_band_defs<F, T>(
         F: FnOnce(&mut LoweringContext) -> T,
     {
         let (in_band_defs, (mut lowered_generics, res)) = self.with_in_scope_lifetime_defs(
-            generics.params.iter().filter_map(|p| match p {
-                GenericParam::Lifetime(ld) => Some(ld),
-                _ => None,
-            }),
+            &generics.params,
             |this| {
                 let itctx = ImplTraitContext::Universal(parent_id);
                 this.collect_in_band_defs(parent_id, anonymous_lifetime_mode, |this| {
@@ -848,6 +839,46 @@ fn with_catch_scope<T, F>(&mut self, catch_id: NodeId, f: F) -> T
         result
     }
 
+    fn make_async_expr(
+        &mut self,
+        capture_clause: CaptureBy,
+        closure_node_id: NodeId,
+        ret_ty: Option<&Ty>,
+        body: impl FnOnce(&mut LoweringContext) -> hir::Expr,
+    ) -> hir::Expr_ {
+        let prev_is_generator = mem::replace(&mut self.is_generator, true);
+        let body_expr = body(self);
+        let span = body_expr.span;
+        let output = match ret_ty {
+            Some(ty) => FunctionRetTy::Ty(P(ty.clone())),
+            None => FunctionRetTy::Default(span),
+        };
+        let decl = FnDecl {
+            inputs: vec![],
+            output,
+            variadic: false
+        };
+        let body_id = self.record_body(body_expr, Some(&decl));
+        self.is_generator = prev_is_generator;
+
+        let capture_clause = self.lower_capture_clause(capture_clause);
+        let closure_hir_id = self.lower_node_id(closure_node_id).hir_id;
+        let decl = self.lower_fn_decl(&decl, None, /* impl trait allowed */ false, false);
+        let generator = hir::Expr {
+            id: closure_node_id,
+            hir_id: closure_hir_id,
+            node: hir::ExprClosure(capture_clause, decl, body_id, span,
+                Some(hir::GeneratorMovability::Static)),
+            span,
+            attrs: ThinVec::new(),
+        };
+
+        let unstable_span = self.allow_internal_unstable(CompilerDesugaringKind::Async, span);
+        let gen_future = self.expr_std_path(
+            unstable_span, &["future", "from_generator"], None, ThinVec::new());
+        hir::ExprCall(P(gen_future), hir_vec![generator])
+    }
+
     fn lower_body<F>(&mut self, decl: Option<&FnDecl>, f: F) -> hir::BodyId
     where
         F: FnOnce(&mut LoweringContext) -> hir::Expr,
@@ -1037,6 +1068,16 @@ fn lower_ty_binding(&mut self, b: &TypeBinding, itctx: ImplTraitContext) -> hir:
         }
     }
 
+    fn lower_generic_arg(&mut self,
+                        arg: &ast::GenericArg,
+                        itctx: ImplTraitContext)
+                        -> hir::GenericArg {
+        match arg {
+            ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt)),
+            ast::GenericArg::Type(ty) => GenericArg::Type(self.lower_ty(&ty, itctx)),
+        }
+    }
+
     fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> P<hir::Ty> {
         let kind = match t.node {
             TyKind::Infer => hir::TyInfer,
@@ -1052,10 +1093,7 @@ fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> P<hir::Ty> {
                 hir::TyRptr(lifetime, self.lower_mt(mt, itctx))
             }
             TyKind::BareFn(ref f) => self.with_in_scope_lifetime_defs(
-                f.generic_params.iter().filter_map(|p| match p {
-                    GenericParam::Lifetime(ld) => Some(ld),
-                    _ => None,
-                }),
+                &f.generic_params,
                 |this| {
                     this.with_anonymous_lifetime_mode(
                         AnonymousLifetimeMode::PassThrough,
@@ -1068,7 +1106,7 @@ fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> P<hir::Ty> {
                                 ),
                                 unsafety: this.lower_unsafety(f.unsafety),
                                 abi: f.abi,
-                                decl: this.lower_fn_decl(&f.decl, None, false),
+                                decl: this.lower_fn_decl(&f.decl, None, false, false),
                                 arg_names: this.lower_fn_args_to_names(&f.decl),
                             }))
                         },
@@ -1110,11 +1148,11 @@ fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> P<hir::Ty> {
                 let bounds = bounds
                     .iter()
                     .filter_map(|bound| match *bound {
-                        TraitTyParamBound(ref ty, TraitBoundModifier::None) => {
+                        GenericBound::Trait(ref ty, TraitBoundModifier::None) => {
                             Some(self.lower_poly_trait_ref(ty, itctx))
                         }
-                        TraitTyParamBound(_, TraitBoundModifier::Maybe) => None,
-                        RegionTyParamBound(ref lifetime) => {
+                        GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
+                        GenericBound::Outlives(ref lifetime) => {
                             if lifetime_bound.is_none() {
                                 lifetime_bound = Some(self.lower_lifetime(lifetime));
                             }
@@ -1133,92 +1171,8 @@ fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> P<hir::Ty> {
                 let span = t.span;
                 match itctx {
                     ImplTraitContext::Existential(fn_def_id) => {
-
-                        // We need to manually repeat the code of `next_id` because the lowering
-                        // needs to happen while the owner_id is pointing to the item itself,
-                        // because items are their own owners
-                        let exist_ty_node_id = self.sess.next_node_id();
-
-                        // Make sure we know that some funky desugaring has been going on here.
-                        // This is a first: there is code in other places like for loop
-                        // desugaring that explicitly states that we don't want to track that.
-                        // Not tracking it makes lints in rustc and clippy very fragile as
-                        // frequently opened issues show.
-                        let exist_ty_span = self.allow_internal_unstable(
-                            CompilerDesugaringKind::ExistentialReturnType,
-                            t.span,
-                        );
-
-                        // Pull a new definition from the ether
-                        let exist_ty_def_index = self
-                            .resolver
-                            .definitions()
-                            .create_def_with_parent(
-                            fn_def_id.index,
-                            exist_ty_node_id,
-                            DefPathData::ExistentialImplTrait,
-                            DefIndexAddressSpace::High,
-                            Mark::root(),
-                            exist_ty_span,
-                        );
-
-                        // the `t` is just for printing debug messages
-                        self.allocate_hir_id_counter(exist_ty_node_id, t);
-
-                        let hir_bounds = self.with_hir_id_owner(exist_ty_node_id, |lctx| {
-                            lctx.lower_bounds(bounds, itctx)
-                        });
-
-                        let (lifetimes, lifetime_defs) = self.lifetimes_from_impl_trait_bounds(
-                            exist_ty_node_id,
-                            exist_ty_def_index,
-                            &hir_bounds,
-                        );
-
-                        self.with_hir_id_owner(exist_ty_node_id, |lctx| {
-                            let exist_ty_item_kind = hir::ItemExistential(hir::ExistTy {
-                                generics: hir::Generics {
-                                    params: lifetime_defs,
-                                    where_clause: hir::WhereClause {
-                                        id: lctx.next_id().node_id,
-                                        predicates: Vec::new().into(),
-                                    },
-                                    span,
-                                },
-                                bounds: hir_bounds,
-                                impl_trait_fn: Some(fn_def_id),
-                            });
-                            let exist_ty_id = lctx.lower_node_id(exist_ty_node_id);
-                            // Generate an `existential type Foo: Trait;` declaration
-                            trace!("creating existential type with id {:#?}", exist_ty_id);
-                            // Set the name to `impl Bound1 + Bound2`
-                            let exist_ty_name = Symbol::intern(&pprust::ty_to_string(t));
-
-                            trace!("exist ty def index: {:#?}", exist_ty_def_index);
-                            let exist_ty_item = hir::Item {
-                                id: exist_ty_id.node_id,
-                                hir_id: exist_ty_id.hir_id,
-                                name: exist_ty_name,
-                                attrs: Default::default(),
-                                node: exist_ty_item_kind,
-                                vis: hir::Visibility::Inherited,
-                                span: exist_ty_span,
-                            };
-
-                            // Insert the item into the global list. This usually happens
-                            // automatically for all AST items. But this existential type item
-                            // does not actually exist in the AST.
-                            lctx.items.insert(exist_ty_id.node_id, exist_ty_item);
-
-                            // `impl Trait` now just becomes `Foo<'a, 'b, ..>`
-                            hir::TyImplTraitExistential(
-                                hir::ItemId {
-                                    id: exist_ty_id.node_id
-                                },
-                                DefId::local(exist_ty_def_index),
-                                lifetimes,
-                            )
-                        })
+                        self.lower_existential_impl_trait(
+                            span, fn_def_id, |this| this.lower_param_bounds(bounds, itctx))
                     }
                     ImplTraitContext::Universal(def_id) => {
                         let def_node_id = self.next_id().node_id;
@@ -1233,18 +1187,20 @@ fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> P<hir::Ty> {
                             span,
                         );
 
-                        let hir_bounds = self.lower_bounds(bounds, itctx);
+                        let hir_bounds = self.lower_param_bounds(bounds, itctx);
                         // Set the name to `impl Bound1 + Bound2`
                         let name = Symbol::intern(&pprust::ty_to_string(t));
-                        self.in_band_ty_params.push(hir::TyParam {
-                            name,
+                        self.in_band_ty_params.push(hir::GenericParam {
                             id: def_node_id,
-                            bounds: hir_bounds,
-                            default: None,
+                            name: ParamName::Plain(name),
                             span,
                             pure_wrt_drop: false,
-                            synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
-                            attrs: P::new(),
+                            attrs: hir_vec![],
+                            bounds: hir_bounds,
+                            kind: hir::GenericParamKind::Type {
+                                default: None,
+                                synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
+                            }
                         });
 
                         hir::TyPath(hir::QPath::Resolved(
@@ -1280,11 +1236,99 @@ fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> P<hir::Ty> {
         })
     }
 
+    fn lower_existential_impl_trait(
+        &mut self,
+        span: Span,
+        fn_def_id: DefId,
+        lower_bounds: impl FnOnce(&mut LoweringContext) -> hir::GenericBounds,
+    ) -> hir::Ty_ {
+        // We need to manually repeat the code of `next_id` because the lowering
+        // needs to happen while the owner_id is pointing to the item itself,
+        // because items are their own owners
+        let exist_ty_node_id = self.sess.next_node_id();
+
+        // Make sure we know that some funky desugaring has been going on here.
+        // This is a first: there is code in other places like for loop
+        // desugaring that explicitly states that we don't want to track that.
+        // Not tracking it makes lints in rustc and clippy very fragile as
+        // frequently opened issues show.
+        let exist_ty_span = self.allow_internal_unstable(
+            CompilerDesugaringKind::ExistentialReturnType,
+            span,
+        );
+
+        // Pull a new definition from the ether
+        let exist_ty_def_index = self
+            .resolver
+            .definitions()
+            .create_def_with_parent(
+            fn_def_id.index,
+            exist_ty_node_id,
+            DefPathData::ExistentialImplTrait,
+            DefIndexAddressSpace::High,
+            Mark::root(),
+            exist_ty_span,
+        );
+
+        self.allocate_hir_id_counter(exist_ty_node_id, &"existential impl trait");
+
+        let hir_bounds = self.with_hir_id_owner(exist_ty_node_id, lower_bounds);
+
+        let (lifetimes, lifetime_defs) = self.lifetimes_from_impl_trait_bounds(
+            exist_ty_node_id,
+            exist_ty_def_index,
+            &hir_bounds,
+        );
+
+        self.with_hir_id_owner(exist_ty_node_id, |lctx| {
+            let exist_ty_item_kind = hir::ItemExistential(hir::ExistTy {
+                generics: hir::Generics {
+                    params: lifetime_defs,
+                    where_clause: hir::WhereClause {
+                        id: lctx.next_id().node_id,
+                        predicates: Vec::new().into(),
+                    },
+                    span,
+                },
+                bounds: hir_bounds,
+                impl_trait_fn: Some(fn_def_id),
+            });
+            let exist_ty_id = lctx.lower_node_id(exist_ty_node_id);
+            // Generate an `existential type Foo: Trait;` declaration
+            trace!("creating existential type with id {:#?}", exist_ty_id);
+
+            trace!("exist ty def index: {:#?}", exist_ty_def_index);
+            let exist_ty_item = hir::Item {
+                id: exist_ty_id.node_id,
+                hir_id: exist_ty_id.hir_id,
+                name: keywords::Invalid.name(),
+                attrs: Default::default(),
+                node: exist_ty_item_kind,
+                vis: hir::Visibility::Inherited,
+                span: exist_ty_span,
+            };
+
+            // Insert the item into the global list. This usually happens
+            // automatically for all AST items. But this existential type item
+            // does not actually exist in the AST.
+            lctx.items.insert(exist_ty_id.node_id, exist_ty_item);
+
+            // `impl Trait` now just becomes `Foo<'a, 'b, ..>`
+            hir::TyImplTraitExistential(
+                hir::ItemId {
+                    id: exist_ty_id.node_id
+                },
+                DefId::local(exist_ty_def_index),
+                lifetimes,
+            )
+        })
+    }
+
     fn lifetimes_from_impl_trait_bounds(
         &mut self,
         exist_ty_id: NodeId,
         parent_index: DefIndex,
-        bounds: &hir::TyParamBounds,
+        bounds: &hir::GenericBounds,
     ) -> (HirVec<hir::Lifetime>, HirVec<hir::GenericParam>) {
         // This visitor walks over impl trait bounds and creates defs for all lifetimes which
         // appear in the bounds, excluding lifetimes that are created within the bounds.
@@ -1307,15 +1351,15 @@ fn nested_visit_map<'this>(
                 hir::intravisit::NestedVisitorMap::None
             }
 
-            fn visit_path_parameters(&mut self, span: Span, parameters: &'v hir::PathParameters) {
+            fn visit_generic_args(&mut self, span: Span, parameters: &'v hir::GenericArgs) {
                 // Don't collect elided lifetimes used inside of `Fn()` syntax.
                 if parameters.parenthesized {
                     let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
                     self.collect_elided_lifetimes = false;
-                    hir::intravisit::walk_path_parameters(self, span, parameters);
+                    hir::intravisit::walk_generic_args(self, span, parameters);
                     self.collect_elided_lifetimes = old_collect_elided_lifetimes;
                 } else {
-                    hir::intravisit::walk_path_parameters(self, span, parameters);
+                    hir::intravisit::walk_generic_args(self, span, parameters);
                 }
             }
 
@@ -1351,10 +1395,11 @@ fn visit_poly_trait_ref(
 
             fn visit_generic_param(&mut self, param: &'v hir::GenericParam) {
                 // Record the introduction of 'a in `for<'a> ...`
-                if let hir::GenericParam::Lifetime(ref lt_def) = *param {
+                if let hir::GenericParamKind::Lifetime { .. } = param.kind {
                     // Introduce lifetimes one at a time so that we can handle
                     // cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>`
-                    self.currently_bound_lifetimes.push(lt_def.lifetime.name);
+                    let lt_name = hir::LifetimeName::Param(param.name);
+                    self.currently_bound_lifetimes.push(lt_name);
                 }
 
                 hir::intravisit::walk_generic_param(self, param);
@@ -1371,14 +1416,12 @@ fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
                             return;
                         }
                     }
-                    name @ hir::LifetimeName::Fresh(_) => name,
-                    name @ hir::LifetimeName::Name(_) => name,
+                    hir::LifetimeName::Param(_) => lifetime.name,
                     hir::LifetimeName::Static => return,
                 };
 
                 if !self.currently_bound_lifetimes.contains(&name)
-                    && !self.already_defined_lifetimes.contains(&name)
-                {
+                    && !self.already_defined_lifetimes.contains(&name) {
                     self.already_defined_lifetimes.insert(name);
 
                     self.output_lifetimes.push(hir::Lifetime {
@@ -1395,23 +1438,31 @@ fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
                     self.context.resolver.definitions().create_def_with_parent(
                         self.parent,
                         def_node_id,
-                        DefPathData::LifetimeDef(name.name().as_interned_str()),
+                        DefPathData::LifetimeParam(name.name().as_interned_str()),
                         DefIndexAddressSpace::High,
                         Mark::root(),
                         lifetime.span,
                     );
-                    let def_lifetime = hir::Lifetime {
+
+                    let name = match name {
+                        hir::LifetimeName::Underscore => {
+                            hir::ParamName::Plain(keywords::UnderscoreLifetime.name())
+                        }
+                        hir::LifetimeName::Param(param_name) => param_name,
+                        _ => bug!("expected LifetimeName::Param or ParamName::Plain"),
+                    };
+
+                    self.output_lifetime_params.push(hir::GenericParam {
                         id: def_node_id,
-                        span: lifetime.span,
                         name,
-                    };
-                    self.output_lifetime_params
-                        .push(hir::GenericParam::Lifetime(hir::LifetimeDef {
-                            lifetime: def_lifetime,
-                            bounds: Vec::new().into(),
-                            pure_wrt_drop: false,
+                        span: lifetime.span,
+                        pure_wrt_drop: false,
+                        attrs: hir_vec![],
+                        bounds: hir_vec![],
+                        kind: hir::GenericParamKind::Lifetime {
                             in_band: false,
-                        }));
+                        }
+                    });
                 }
             }
         }
@@ -1428,7 +1479,7 @@ fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
         };
 
         for bound in bounds {
-            hir::intravisit::walk_ty_param_bound(&mut lifetime_collector, &bound);
+            hir::intravisit::walk_param_bound(&mut lifetime_collector, &bound);
         }
 
         (
@@ -1669,13 +1720,13 @@ fn lower_path_segment(
         parenthesized_generic_args: ParenthesizedGenericArgs,
         itctx: ImplTraitContext,
     ) -> hir::PathSegment {
-        let (mut parameters, infer_types) = if let Some(ref parameters) = segment.parameters {
+        let (mut generic_args, infer_types) = if let Some(ref generic_args) = segment.args {
             let msg = "parenthesized parameters may only be used with a trait";
-            match **parameters {
-                PathParameters::AngleBracketed(ref data) => {
+            match **generic_args {
+                GenericArgs::AngleBracketed(ref data) => {
                     self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
                 }
-                PathParameters::Parenthesized(ref data) => match parenthesized_generic_args {
+                GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args {
                     ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
                     ParenthesizedGenericArgs::Warn => {
                         self.sess.buffer_lint(
@@ -1684,13 +1735,13 @@ fn lower_path_segment(
                             data.span,
                             msg.into(),
                         );
-                        (hir::PathParameters::none(), true)
+                        (hir::GenericArgs::none(), true)
                     }
                     ParenthesizedGenericArgs::Err => {
                         struct_span_err!(self.sess, data.span, E0214, "{}", msg)
                             .span_label(data.span, "only traits may use parentheses")
                             .emit();
-                        (hir::PathParameters::none(), true)
+                        (hir::GenericArgs::none(), true)
                     }
                 },
             }
@@ -1698,47 +1749,49 @@ fn lower_path_segment(
             self.lower_angle_bracketed_parameter_data(&Default::default(), param_mode, itctx)
         };
 
-        if !parameters.parenthesized && parameters.lifetimes.is_empty() {
-            parameters.lifetimes = self.elided_path_lifetimes(path_span, expected_lifetimes);
+        let has_lifetimes = generic_args.args.iter().any(|arg| match arg {
+            GenericArg::Lifetime(_) => true,
+            _ => false,
+        });
+        if !generic_args.parenthesized && !has_lifetimes {
+            generic_args.args =
+                self.elided_path_lifetimes(path_span, expected_lifetimes)
+                    .into_iter()
+                    .map(|lt| GenericArg::Lifetime(lt))
+                    .chain(generic_args.args.into_iter())
+                    .collect();
         }
 
         hir::PathSegment::new(
             self.lower_ident(segment.ident),
-            parameters,
+            generic_args,
             infer_types,
         )
     }
 
     fn lower_angle_bracketed_parameter_data(
         &mut self,
-        data: &AngleBracketedParameterData,
+        data: &AngleBracketedArgs,
         param_mode: ParamMode,
         itctx: ImplTraitContext,
-    ) -> (hir::PathParameters, bool) {
-        let &AngleBracketedParameterData {
-            ref lifetimes,
-            ref types,
-            ref bindings,
-            ..
-        } = data;
-        (
-            hir::PathParameters {
-                lifetimes: self.lower_lifetimes(lifetimes),
-                types: types.iter().map(|ty| self.lower_ty(ty, itctx)).collect(),
-                bindings: bindings
-                    .iter()
-                    .map(|b| self.lower_ty_binding(b, itctx))
-                    .collect(),
-                parenthesized: false,
-            },
-            types.is_empty() && param_mode == ParamMode::Optional,
-        )
+    ) -> (hir::GenericArgs, bool) {
+        let &AngleBracketedArgs { ref args, ref bindings, .. } = data;
+        let has_types = args.iter().any(|arg| match arg {
+            ast::GenericArg::Type(_) => true,
+            _ => false,
+        });
+        (hir::GenericArgs {
+            args: args.iter().map(|a| self.lower_generic_arg(a, itctx)).collect(),
+            bindings: bindings.iter().map(|b| self.lower_ty_binding(b, itctx)).collect(),
+            parenthesized: false,
+        },
+        !has_types && param_mode == ParamMode::Optional)
     }
 
     fn lower_parenthesized_parameter_data(
         &mut self,
-        data: &ParenthesizedParameterData,
-    ) -> (hir::PathParameters, bool) {
+        data: &ParenthesisedArgs,
+    ) -> (hir::GenericArgs, bool) {
         // Switch to `PassThrough` mode for anonymous lifetimes: this
         // means that we permit things like `&Ref<T>`, where `Ref` has
         // a hidden lifetime parameter. This is needed for backwards
@@ -1748,29 +1801,16 @@ fn lower_parenthesized_parameter_data(
             AnonymousLifetimeMode::PassThrough,
             |this| {
                 const DISALLOWED: ImplTraitContext = ImplTraitContext::Disallowed;
-                let &ParenthesizedParameterData {
-                    ref inputs,
-                    ref output,
-                    span,
-                } = data;
-                let inputs = inputs
-                    .iter()
-                    .map(|ty| this.lower_ty(ty, DISALLOWED))
-                    .collect();
+                let &ParenthesisedArgs { ref inputs, ref output, span } = data;
+                let inputs = inputs.iter().map(|ty| this.lower_ty(ty, DISALLOWED)).collect();
                 let mk_tup = |this: &mut Self, tys, span| {
                     let LoweredNodeId { node_id, hir_id } = this.next_id();
-                    P(hir::Ty {
-                        node: hir::TyTup(tys),
-                        id: node_id,
-                        hir_id,
-                        span,
-                    })
+                    P(hir::Ty { node: hir::TyTup(tys), id: node_id, hir_id, span })
                 };
 
                 (
-                    hir::PathParameters {
-                        lifetimes: hir::HirVec::new(),
-                        types: hir_vec![mk_tup(this, inputs, span)],
+                    hir::GenericArgs {
+                        args: hir_vec![GenericArg::Type(mk_tup(this, inputs, span))],
                         bindings: hir_vec![
                             hir::TypeBinding {
                                 id: this.next_id().node_id,
@@ -1832,31 +1872,40 @@ fn lower_fn_args_to_names(&mut self, decl: &FnDecl) -> hir::HirVec<Spanned<Name>
             .collect()
     }
 
+    // Lowers a function declaration.
+    //
+    // decl: the unlowered (ast) function declaration.
+    // fn_def_id: if `Some`, impl Trait arguments are lowered into generic parameters on the
+    //      given DefId, otherwise impl Trait is disallowed. Must be `Some` if
+    //      make_ret_async is true.
+    // impl_trait_return_allow: determines whether impl Trait can be used in return position.
+    //      This guards against trait declarations and implementations where impl Trait is
+    //      disallowed.
+    // make_ret_async: if enabled, converts `-> T` into `-> impl Future<Output = T>` in the
+    //      return type. This is used for `async fn` declarations.
     fn lower_fn_decl(
         &mut self,
         decl: &FnDecl,
         fn_def_id: Option<DefId>,
         impl_trait_return_allow: bool,
+        make_ret_async: bool,
     ) -> P<hir::FnDecl> {
-        // NOTE: The two last parameters here have to do with impl Trait. If fn_def_id is Some,
-        //       then impl Trait arguments are lowered into generic parameters on the given
-        //       fn_def_id, otherwise impl Trait is disallowed. (for now)
-        //
-        //       Furthermore, if impl_trait_return_allow is true, then impl Trait may be used in
-        //       return positions as well. This guards against trait declarations and their impls
-        //       where impl Trait is disallowed. (again for now)
-        P(hir::FnDecl {
-            inputs: decl.inputs
-                .iter()
-                .map(|arg| {
-                    if let Some(def_id) = fn_def_id {
-                        self.lower_ty(&arg.ty, ImplTraitContext::Universal(def_id))
-                    } else {
-                        self.lower_ty(&arg.ty, ImplTraitContext::Disallowed)
-                    }
-                })
-                .collect(),
-            output: match decl.output {
+        let inputs = decl.inputs
+            .iter()
+            .map(|arg| {
+                if let Some(def_id) = fn_def_id {
+                    self.lower_ty(&arg.ty, ImplTraitContext::Universal(def_id))
+                } else {
+                    self.lower_ty(&arg.ty, ImplTraitContext::Disallowed)
+                }
+            })
+            .collect::<HirVec<_>>();
+
+        let output = if make_ret_async {
+            self.lower_async_fn_ret_ty(
+                &inputs, &decl.output, fn_def_id.expect("make_ret_async but no fn_def_id"))
+        } else {
+            match decl.output {
                 FunctionRetTy::Ty(ref ty) => match fn_def_id {
                     Some(def_id) if impl_trait_return_allow => {
                         hir::Return(self.lower_ty(ty, ImplTraitContext::Existential(def_id)))
@@ -1864,7 +1913,12 @@ fn lower_fn_decl(
                     _ => hir::Return(self.lower_ty(ty, ImplTraitContext::Disallowed)),
                 },
                 FunctionRetTy::Default(span) => hir::DefaultReturn(span),
-            },
+            }
+        };
+
+        P(hir::FnDecl {
+            inputs,
+            output,
             variadic: decl.variadic,
             has_implicit_self: decl.inputs.get(0).map_or(false, |arg| match arg.ty.node {
                 TyKind::ImplicitSelf => true,
@@ -1874,60 +1928,244 @@ fn lower_fn_decl(
         })
     }
 
-    fn lower_ty_param_bound(
+    // Transform `-> T` into `-> impl Future<Output = T>` for `async fn`
+    //
+    // fn_span: the span of the async function declaration. Used for error reporting.
+    // inputs: lowered types of arguments to the function. Used to collect lifetimes.
+    // output: unlowered output type (`T` in `-> T`)
+    // fn_def_id: DefId of the parent function. Used to create child impl trait definition.
+    fn lower_async_fn_ret_ty(
         &mut self,
-        tpb: &TyParamBound,
-        itctx: ImplTraitContext,
-    ) -> hir::TyParamBound {
-        match *tpb {
-            TraitTyParamBound(ref ty, modifier) => hir::TraitTyParamBound(
-                self.lower_poly_trait_ref(ty, itctx),
-                self.lower_trait_bound_modifier(modifier),
-            ),
-            RegionTyParamBound(ref lifetime) => {
-                hir::RegionTyParamBound(self.lower_lifetime(lifetime))
+        inputs: &[P<hir::Ty>],
+        output: &FunctionRetTy,
+        fn_def_id: DefId,
+    ) -> hir::FunctionRetTy {
+        // Get lifetimes used in the input arguments to the function. Our output type must also
+        // have the same lifetime. FIXME(cramertj) multiple different lifetimes are not allowed
+        // because `impl Trait + 'a + 'b` doesn't allow for capture `'a` and `'b` where neither
+        // is a subset of the other. We really want some new lifetime that is a subset of all input
+        // lifetimes, but that doesn't exist at the moment.
+
+        struct AsyncFnLifetimeCollector<'r, 'a: 'r> {
+            context: &'r mut LoweringContext<'a>,
+            // Lifetimes bound by HRTB
+            currently_bound_lifetimes: Vec<hir::LifetimeName>,
+            // Whether to count elided lifetimes.
+            // Disabled inside of `Fn` or `fn` syntax.
+            collect_elided_lifetimes: bool,
+            // The lifetime found.
+            // Multiple different or elided lifetimes cannot appear in async fn for now.
+            output_lifetime: Option<(hir::LifetimeName, Span)>,
+        }
+
+        impl<'r, 'a: 'r, 'v> hir::intravisit::Visitor<'v> for AsyncFnLifetimeCollector<'r, 'a> {
+            fn nested_visit_map<'this>(
+                &'this mut self,
+            ) -> hir::intravisit::NestedVisitorMap<'this, 'v> {
+                hir::intravisit::NestedVisitorMap::None
+            }
+
+            fn visit_generic_args(&mut self, span: Span, parameters: &'v hir::GenericArgs) {
+                // Don't collect elided lifetimes used inside of `Fn()` syntax.
+                if parameters.parenthesized {
+                    let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
+                    self.collect_elided_lifetimes = false;
+                    hir::intravisit::walk_generic_args(self, span, parameters);
+                    self.collect_elided_lifetimes = old_collect_elided_lifetimes;
+                } else {
+                    hir::intravisit::walk_generic_args(self, span, parameters);
+                }
+            }
+
+            fn visit_ty(&mut self, t: &'v hir::Ty) {
+                // Don't collect elided lifetimes used inside of `fn()` syntax
+                if let &hir::Ty_::TyBareFn(_) = &t.node {
+                    let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
+                    self.collect_elided_lifetimes = false;
+
+                    // Record the "stack height" of `for<'a>` lifetime bindings
+                    // to be able to later fully undo their introduction.
+                    let old_len = self.currently_bound_lifetimes.len();
+                    hir::intravisit::walk_ty(self, t);
+                    self.currently_bound_lifetimes.truncate(old_len);
+
+                    self.collect_elided_lifetimes = old_collect_elided_lifetimes;
+                } else {
+                    hir::intravisit::walk_ty(self, t);
+                }
+            }
+
+            fn visit_poly_trait_ref(
+                &mut self,
+                trait_ref: &'v hir::PolyTraitRef,
+                modifier: hir::TraitBoundModifier,
+            ) {
+                // Record the "stack height" of `for<'a>` lifetime bindings
+                // to be able to later fully undo their introduction.
+                let old_len = self.currently_bound_lifetimes.len();
+                hir::intravisit::walk_poly_trait_ref(self, trait_ref, modifier);
+                self.currently_bound_lifetimes.truncate(old_len);
+            }
+
+            fn visit_generic_param(&mut self, param: &'v hir::GenericParam) {
+                 // Record the introduction of 'a in `for<'a> ...`
+                if let hir::GenericParamKind::Lifetime { .. } = param.kind {
+                    // Introduce lifetimes one at a time so that we can handle
+                    // cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>`
+                    let lt_name = hir::LifetimeName::Param(param.name);
+                    self.currently_bound_lifetimes.push(lt_name);
+                }
+
+                hir::intravisit::walk_generic_param(self, param);
+            }
+
+            fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
+                let name = match lifetime.name {
+                    hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => {
+                        if self.collect_elided_lifetimes {
+                            // Use `'_` for both implicit and underscore lifetimes in
+                            // `abstract type Foo<'_>: SomeTrait<'_>;`
+                            hir::LifetimeName::Underscore
+                        } else {
+                            return;
+                        }
+                    }
+                    hir::LifetimeName::Param(_) => lifetime.name,
+                    hir::LifetimeName::Static => return,
+                };
+
+                if !self.currently_bound_lifetimes.contains(&name) {
+                    if let Some((current_lt_name, current_lt_span)) = self.output_lifetime {
+                        // We don't currently have a reliable way to desugar `async fn` with
+                        // multiple potentially unrelated input lifetimes into
+                        // `-> impl Trait + 'lt`, so we report an error in this case.
+                        if current_lt_name != name {
+                            struct_span_err!(
+                                self.context.sess,
+                                current_lt_span.between(lifetime.span),
+                                E0709,
+                                "multiple different lifetimes used in arguments of `async fn`",
+                            )
+                                .span_label(current_lt_span, "first lifetime here")
+                                .span_label(lifetime.span, "different lifetime here")
+                                .help("`async fn` can only accept borrowed values \
+                                      with identical lifetimes")
+                                .emit()
+                        } else if current_lt_name.is_elided() && name.is_elided() {
+                            struct_span_err!(
+                                self.context.sess,
+                                current_lt_span.between(lifetime.span),
+                                E0707,
+                                "multiple elided lifetimes used in arguments of `async fn`",
+                            )
+                                .span_label(current_lt_span, "first lifetime here")
+                                .span_label(lifetime.span, "different lifetime here")
+                                .help("consider giving these arguments named lifetimes")
+                                .emit()
+                        }
+                    } else {
+                        self.output_lifetime = Some((name, lifetime.span));
+                    }
+                }
             }
         }
+
+        let bound_lifetime = {
+            let mut lifetime_collector = AsyncFnLifetimeCollector {
+                context: self,
+                currently_bound_lifetimes: Vec::new(),
+                collect_elided_lifetimes: true,
+                output_lifetime: None,
+            };
+
+            for arg in inputs {
+                hir::intravisit::walk_ty(&mut lifetime_collector, arg);
+            }
+            lifetime_collector.output_lifetime
+        };
+
+        let span = match output {
+            FunctionRetTy::Ty(ty) => ty.span,
+            FunctionRetTy::Default(span) => *span,
+        };
+
+        let impl_trait_ty = self.lower_existential_impl_trait(
+            span, fn_def_id, |this| {
+            let output_ty = match output {
+                FunctionRetTy::Ty(ty) =>
+                    this.lower_ty(ty, ImplTraitContext::Existential(fn_def_id)),
+                FunctionRetTy::Default(span) => {
+                    let LoweredNodeId { node_id, hir_id } = this.next_id();
+                    P(hir::Ty {
+                        id: node_id,
+                        hir_id: hir_id,
+                        node: hir::TyTup(hir_vec![]),
+                        span: *span,
+                    })
+                }
+            };
+
+            // "<Output = T>"
+            let future_params = P(hir::GenericArgs {
+                args: hir_vec![],
+                bindings: hir_vec![hir::TypeBinding {
+                    name: Symbol::intern(FN_OUTPUT_NAME),
+                    ty: output_ty,
+                    id: this.next_id().node_id,
+                    span,
+                }],
+                parenthesized: false,
+            });
+
+            let future_path =
+                this.std_path(span, &["future", "Future"], Some(future_params), false);
+
+            let mut bounds = vec![
+                hir::GenericBound::Trait(
+                    hir::PolyTraitRef {
+                        trait_ref: hir::TraitRef {
+                            path: future_path,
+                            ref_id: this.next_id().node_id,
+                        },
+                        bound_generic_params: hir_vec![],
+                        span,
+                    },
+                    hir::TraitBoundModifier::None
+                ),
+            ];
+
+            if let Some((name, span)) = bound_lifetime {
+                bounds.push(hir::GenericBound::Outlives(
+                    hir::Lifetime { id: this.next_id().node_id, name, span }));
+            }
+
+            hir::HirVec::from(bounds)
+        });
+
+        let LoweredNodeId { node_id, hir_id } = self.next_id();
+        let impl_trait_ty = P(hir::Ty {
+            id: node_id,
+            node: impl_trait_ty,
+            span,
+            hir_id,
+        });
+
+        hir::FunctionRetTy::Return(impl_trait_ty)
     }
 
-    fn lower_ty_param(
+    fn lower_param_bound(
         &mut self,
-        tp: &TyParam,
-        add_bounds: &[TyParamBound],
+        tpb: &GenericBound,
         itctx: ImplTraitContext,
-    ) -> hir::TyParam {
-        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`.
-        // Instead, use gensym("Self") to create a distinct name that looks the same.
-        if name == keywords::SelfType.name() {
-            name = Symbol::gensym("Self");
-        }
-
-        let mut bounds = self.lower_bounds(&tp.bounds, itctx);
-        if !add_bounds.is_empty() {
-            bounds = bounds
-                .into_iter()
-                .chain(self.lower_bounds(add_bounds, itctx).into_iter())
-                .collect();
-        }
-
-        hir::TyParam {
-            id: self.lower_node_id(tp.id).node_id,
-            name,
-            bounds,
-            default: tp.default
-                .as_ref()
-                .map(|x| self.lower_ty(x, ImplTraitContext::Disallowed)),
-            span: tp.ident.span,
-            pure_wrt_drop: attr::contains_name(&tp.attrs, "may_dangle"),
-            synthetic: tp.attrs
-                .iter()
-                .filter(|attr| attr.check_name("rustc_synthetic"))
-                .map(|_| hir::SyntheticTyParamKind::ImplTrait)
-                .nth(0),
-            attrs: self.lower_attrs(&tp.attrs),
+    ) -> hir::GenericBound {
+        match *tpb {
+            GenericBound::Trait(ref ty, modifier) => hir::GenericBound::Trait(
+                self.lower_poly_trait_ref(ty, itctx),
+                self.lower_trait_bound_modifier(modifier),
+            ),
+            GenericBound::Outlives(ref lifetime) => {
+                hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
+            }
         }
     }
 
@@ -1938,7 +2176,7 @@ fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
             x if x == "'_" => match self.anonymous_lifetime_mode {
                 AnonymousLifetimeMode::CreateParameter => {
                     let fresh_name = self.collect_fresh_in_band_lifetime(span);
-                    self.new_named_lifetime(l.id, span, fresh_name)
+                    self.new_named_lifetime(l.id, span, hir::LifetimeName::Param(fresh_name))
                 }
 
                 AnonymousLifetimeMode::PassThrough => {
@@ -1947,7 +2185,8 @@ fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
             },
             name => {
                 self.maybe_collect_in_band_lifetime(span, name);
-                self.new_named_lifetime(l.id, span, hir::LifetimeName::Name(name))
+                let param_name = ParamName::Plain(name);
+                self.new_named_lifetime(l.id, span, hir::LifetimeName::Param(param_name))
             }
         }
     }
@@ -1965,57 +2204,98 @@ fn new_named_lifetime(
         }
     }
 
-    fn lower_lifetime_def(&mut self, l: &LifetimeDef) -> hir::LifetimeDef {
-        let was_collecting_in_band = self.is_collecting_in_band_lifetimes;
-        self.is_collecting_in_band_lifetimes = false;
-
-        let def = hir::LifetimeDef {
-            lifetime: self.lower_lifetime(&l.lifetime),
-            bounds: self.lower_lifetimes(&l.bounds),
-            pure_wrt_drop: attr::contains_name(&l.attrs, "may_dangle"),
-            in_band: false,
-        };
-
-        self.is_collecting_in_band_lifetimes = was_collecting_in_band;
-
-        def
-    }
-
-    fn lower_lifetimes(&mut self, lts: &Vec<Lifetime>) -> hir::HirVec<hir::Lifetime> {
-        lts.iter().map(|l| self.lower_lifetime(l)).collect()
-    }
-
     fn lower_generic_params(
         &mut self,
         params: &Vec<GenericParam>,
-        add_bounds: &NodeMap<Vec<TyParamBound>>,
+        add_bounds: &NodeMap<Vec<GenericBound>>,
         itctx: ImplTraitContext,
     ) -> hir::HirVec<hir::GenericParam> {
-        params
-            .iter()
-            .map(|param| match *param {
-                GenericParam::Lifetime(ref lifetime_def) => {
-                    hir::GenericParam::Lifetime(self.lower_lifetime_def(lifetime_def))
+        params.iter().map(|param| self.lower_generic_param(param, add_bounds, itctx)).collect()
+    }
+
+    fn lower_generic_param(&mut self,
+                           param: &GenericParam,
+                           add_bounds: &NodeMap<Vec<GenericBound>>,
+                           itctx: ImplTraitContext)
+                           -> hir::GenericParam {
+        let mut bounds = self.lower_param_bounds(&param.bounds, itctx);
+        match param.kind {
+            GenericParamKind::Lifetime => {
+                let was_collecting_in_band = self.is_collecting_in_band_lifetimes;
+                self.is_collecting_in_band_lifetimes = false;
+
+                let lt = self.lower_lifetime(&Lifetime { id: param.id, ident: param.ident });
+                let param_name = match lt.name {
+                    hir::LifetimeName::Param(param_name) => param_name,
+                    _ => hir::ParamName::Plain(lt.name.name()),
+                };
+                let param = hir::GenericParam {
+                    id: lt.id,
+                    name: param_name,
+                    span: lt.span,
+                    pure_wrt_drop: attr::contains_name(&param.attrs, "may_dangle"),
+                    attrs: self.lower_attrs(&param.attrs),
+                    bounds,
+                    kind: hir::GenericParamKind::Lifetime { in_band: false }
+                };
+
+                self.is_collecting_in_band_lifetimes = was_collecting_in_band;
+
+                param
+            }
+            GenericParamKind::Type { ref default, .. } => {
+                let mut name = self.lower_ident(param.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`.
+                // Instead, use gensym("Self") to create a distinct name that looks the same.
+                if name == keywords::SelfType.name() {
+                    name = Symbol::gensym("Self");
                 }
-                GenericParam::Type(ref ty_param) => hir::GenericParam::Type(self.lower_ty_param(
-                    ty_param,
-                    add_bounds.get(&ty_param.id).map_or(&[][..], |x| &x),
-                    itctx,
-                )),
-            })
-            .collect()
+
+                let add_bounds = add_bounds.get(&param.id).map_or(&[][..], |x| &x);
+                if !add_bounds.is_empty() {
+                    bounds = bounds.into_iter()
+                                   .chain(self.lower_param_bounds(add_bounds, itctx).into_iter())
+                                   .collect();
+                }
+
+                hir::GenericParam {
+                    id: self.lower_node_id(param.id).node_id,
+                    name: hir::ParamName::Plain(name),
+                    span: param.ident.span,
+                    pure_wrt_drop: attr::contains_name(&param.attrs, "may_dangle"),
+                    attrs: self.lower_attrs(&param.attrs),
+                    bounds,
+                    kind: hir::GenericParamKind::Type {
+                        default: default.as_ref().map(|x| {
+                            self.lower_ty(x, ImplTraitContext::Disallowed)
+                        }),
+                        synthetic: param.attrs.iter()
+                                              .filter(|attr| attr.check_name("rustc_synthetic"))
+                                              .map(|_| hir::SyntheticTyParamKind::ImplTrait)
+                                              .next(),
+                    }
+                }
+            }
+        }
     }
 
-    fn lower_generics(&mut self, g: &Generics, itctx: ImplTraitContext) -> hir::Generics {
+    fn lower_generics(
+        &mut self,
+        generics: &Generics,
+        itctx: ImplTraitContext)
+        -> hir::Generics
+    {
         // Collect `?Trait` bounds in where clause and move them to parameter definitions.
         // FIXME: This could probably be done with less rightward drift. Also looks like two control
         //        paths where report_error is called are also the only paths that advance to after
         //        the match statement, so the error reporting could probably just be moved there.
         let mut add_bounds = NodeMap();
-        for pred in &g.where_clause.predicates {
+        for pred in &generics.where_clause.predicates {
             if let WherePredicate::BoundPredicate(ref bound_pred) = *pred {
                 'next_bound: for bound in &bound_pred.bounds {
-                    if let TraitTyParamBound(_, TraitBoundModifier::Maybe) = *bound {
+                    if let GenericBound::Trait(_, TraitBoundModifier::Maybe) = *bound {
                         let report_error = |this: &mut Self| {
                             this.diagnostic().span_err(
                                 bound_pred.bounded_ty.span,
@@ -2036,15 +2316,17 @@ fn lower_generics(&mut self, g: &Generics, itctx: ImplTraitContext) -> hir::Gene
                                     if let Some(node_id) =
                                         self.resolver.definitions().as_local_node_id(def_id)
                                     {
-                                        for param in &g.params {
-                                            if let GenericParam::Type(ref ty_param) = *param {
-                                                if node_id == ty_param.id {
-                                                    add_bounds
-                                                        .entry(ty_param.id)
-                                                        .or_insert(Vec::new())
-                                                        .push(bound.clone());
-                                                    continue 'next_bound;
+                                        for param in &generics.params {
+                                            match param.kind {
+                                                GenericParamKind::Type { .. } => {
+                                                    if node_id == param.id {
+                                                        add_bounds.entry(param.id)
+                                                            .or_insert(Vec::new())
+                                                            .push(bound.clone());
+                                                        continue 'next_bound;
+                                                    }
                                                 }
+                                                _ => {}
                                             }
                                         }
                                     }
@@ -2059,9 +2341,9 @@ fn lower_generics(&mut self, g: &Generics, itctx: ImplTraitContext) -> hir::Gene
         }
 
         hir::Generics {
-            params: self.lower_generic_params(&g.params, &add_bounds, itctx),
-            where_clause: self.lower_where_clause(&g.where_clause),
-            span: g.span,
+            params: self.lower_generic_params(&generics.params, &add_bounds, itctx),
+            where_clause: self.lower_where_clause(&generics.where_clause),
+            span: generics.span,
         }
     }
 
@@ -2084,10 +2366,7 @@ fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicat
                 span,
             }) => {
                 self.with_in_scope_lifetime_defs(
-                    bound_generic_params.iter().filter_map(|p| match p {
-                        GenericParam::Lifetime(ld) => Some(ld),
-                        _ => None,
-                    }),
+                    &bound_generic_params,
                     |this| {
                         hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
                             bound_generic_params: this.lower_generic_params(
@@ -2101,8 +2380,8 @@ fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicat
                                 .filter_map(|bound| match *bound {
                                     // Ignore `?Trait` bounds.
                                     // Tthey were copied into type parameters already.
-                                    TraitTyParamBound(_, TraitBoundModifier::Maybe) => None,
-                                    _ => Some(this.lower_ty_param_bound(
+                                    GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
+                                    _ => Some(this.lower_param_bound(
                                         bound,
                                         ImplTraitContext::Disallowed,
                                     )),
@@ -2120,10 +2399,7 @@ fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicat
             }) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
                 span,
                 lifetime: self.lower_lifetime(lifetime),
-                bounds: bounds
-                    .iter()
-                    .map(|bound| self.lower_lifetime(bound))
-                    .collect(),
+                bounds: self.lower_param_bounds(bounds, ImplTraitContext::Disallowed),
             }),
             WherePredicate::EqPredicate(WhereEqPredicate {
                 id,
@@ -2180,13 +2456,7 @@ fn lower_poly_trait_ref(
         let bound_generic_params =
             self.lower_generic_params(&p.bound_generic_params, &NodeMap(), itctx);
         let trait_ref = self.with_parent_impl_lifetime_defs(
-            &bound_generic_params
-                .iter()
-                .filter_map(|p| match *p {
-                    hir::GenericParam::Lifetime(ref ld) => Some(ld.clone()),
-                    _ => None,
-                })
-                .collect::<Vec<_>>(),
+            &bound_generic_params,
             |this| this.lower_trait_ref(&p.trait_ref, itctx),
         );
 
@@ -2229,15 +2499,9 @@ fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy {
         }
     }
 
-    fn lower_bounds(
-        &mut self,
-        bounds: &[TyParamBound],
-        itctx: ImplTraitContext,
-    ) -> hir::TyParamBounds {
-        bounds
-            .iter()
-            .map(|bound| self.lower_ty_param_bound(bound, itctx))
-            .collect()
+    fn lower_param_bounds(&mut self, bounds: &[GenericBound], itctx: ImplTraitContext)
+        -> hir::GenericBounds {
+        bounds.iter().map(|bound| self.lower_param_bound(bound, itctx)).collect()
     }
 
     fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> P<hir::Block> {
@@ -2302,25 +2566,40 @@ fn lower_item_kind(
                 let value = self.lower_body(None, |this| this.lower_expr(e));
                 hir::ItemConst(self.lower_ty(t, ImplTraitContext::Disallowed), value)
             }
-            ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
+            ItemKind::Fn(ref decl, header, ref generics, ref body) => {
                 let fn_def_id = self.resolver.definitions().local_def_id(id);
+
                 self.with_new_scopes(|this| {
+                    // Note: we don't need to change the return type from `T` to
+                    // `impl Future<Output = T>` here because lower_body
+                    // only cares about the input argument patterns in the function
+                    // declaration (decl), not the return types.
                     let body_id = this.lower_body(Some(decl), |this| {
-                        let body = this.lower_block(body, false);
-                        this.expr_block(body, ThinVec::new())
+                        if let IsAsync::Async(async_node_id) = header.asyncness {
+                            let async_expr = this.make_async_expr(
+                                CaptureBy::Value, async_node_id, None,
+                                |this| {
+                                    let body = this.lower_block(body, false);
+                                    this.expr_block(body, ThinVec::new())
+                                });
+                            this.expr(body.span, async_expr, ThinVec::new())
+                        } else {
+                            let body = this.lower_block(body, false);
+                            this.expr_block(body, ThinVec::new())
+                        }
                     });
+
                     let (generics, fn_decl) = this.add_in_band_defs(
                         generics,
                         fn_def_id,
                         AnonymousLifetimeMode::PassThrough,
-                        |this| this.lower_fn_decl(decl, Some(fn_def_id), true),
+                        |this| this.lower_fn_decl(
+                            decl, Some(fn_def_id), true, header.asyncness.is_async())
                     );
 
                     hir::ItemFn(
                         fn_decl,
-                        this.lower_unsafety(unsafety),
-                        this.lower_constness(constness),
-                        abi,
+                        this.lower_fn_header(header),
                         generics,
                         body_id,
                     )
@@ -2403,10 +2682,7 @@ fn lower_item_kind(
                 );
 
                 let new_impl_items = self.with_in_scope_lifetime_defs(
-                    ast_generics.params.iter().filter_map(|p| match p {
-                        GenericParam::Lifetime(ld) => Some(ld),
-                        _ => None,
-                    }),
+                    &ast_generics.params,
                     |this| {
                         impl_items
                             .iter()
@@ -2426,7 +2702,7 @@ fn lower_item_kind(
                 )
             }
             ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
-                let bounds = self.lower_bounds(bounds, ImplTraitContext::Disallowed);
+                let bounds = self.lower_param_bounds(bounds, ImplTraitContext::Disallowed);
                 let items = items
                     .iter()
                     .map(|item| self.lower_trait_item_ref(item))
@@ -2441,7 +2717,7 @@ fn lower_item_kind(
             }
             ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemTraitAlias(
                 self.lower_generics(generics, ImplTraitContext::Disallowed),
-                self.lower_bounds(bounds, ImplTraitContext::Disallowed),
+                self.lower_param_bounds(bounds, ImplTraitContext::Disallowed),
             ),
             ItemKind::MacroDef(..) | ItemKind::Mac(..) => panic!("Shouldn't still be around"),
         }
@@ -2641,7 +2917,7 @@ fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
                     AnonymousLifetimeMode::PassThrough,
                     |this| {
                         hir::TraitItemKind::Method(
-                            this.lower_method_sig(sig, trait_item_def_id, false),
+                            this.lower_method_sig(sig, trait_item_def_id, false, false),
                             hir::TraitMethod::Required(names),
                         )
                     },
@@ -2659,7 +2935,7 @@ fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
                     AnonymousLifetimeMode::PassThrough,
                     |this| {
                         hir::TraitItemKind::Method(
-                            this.lower_method_sig(sig, trait_item_def_id, false),
+                            this.lower_method_sig(sig, trait_item_def_id, false, false),
                             hir::TraitMethod::Provided(body_id),
                         )
                     },
@@ -2668,7 +2944,7 @@ fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
             TraitItemKind::Type(ref bounds, ref default) => (
                 self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
                 hir::TraitItemKind::Type(
-                    self.lower_bounds(bounds, ImplTraitContext::Disallowed),
+                    self.lower_param_bounds(bounds, ImplTraitContext::Disallowed),
                     default
                         .as_ref()
                         .map(|x| self.lower_ty(x, ImplTraitContext::Disallowed)),
@@ -2730,8 +3006,18 @@ fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
             }
             ImplItemKind::Method(ref sig, ref body) => {
                 let body_id = self.lower_body(Some(&sig.decl), |this| {
-                    let body = this.lower_block(body, false);
-                    this.expr_block(body, ThinVec::new())
+                    if let IsAsync::Async(async_node_id) = sig.header.asyncness {
+                        let async_expr = this.make_async_expr(
+                            CaptureBy::Value, async_node_id, None,
+                            |this| {
+                                let body = this.lower_block(body, false);
+                                this.expr_block(body, ThinVec::new())
+                            });
+                        this.expr(body.span, async_expr, ThinVec::new())
+                    } else {
+                        let body = this.lower_block(body, false);
+                        this.expr_block(body, ThinVec::new())
+                    }
                 });
                 let impl_trait_return_allow = !self.is_in_trait_impl;
 
@@ -2745,6 +3031,7 @@ fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
                                 sig,
                                 impl_item_def_id,
                                 impl_trait_return_allow,
+                                sig.header.asyncness.is_async(),
                             ),
                             body_id,
                         )
@@ -2886,7 +3173,7 @@ fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
                         |this| {
                             (
                                 // Disallow impl Trait in foreign items
-                                this.lower_fn_decl(fdec, None, false),
+                                this.lower_fn_decl(fdec, None, false, false),
                                 this.lower_fn_args_to_names(fdec),
                             )
                         },
@@ -2910,12 +3197,11 @@ fn lower_method_sig(
         sig: &MethodSig,
         fn_def_id: DefId,
         impl_trait_return_allow: bool,
+        is_async: bool,
     ) -> hir::MethodSig {
         hir::MethodSig {
-            abi: sig.abi,
-            unsafety: self.lower_unsafety(sig.unsafety),
-            constness: self.lower_constness(sig.constness),
-            decl: self.lower_fn_decl(&sig.decl, Some(fn_def_id), impl_trait_return_allow),
+            header: self.lower_fn_header(sig.header),
+            decl: self.lower_fn_decl(&sig.decl, Some(fn_def_id), impl_trait_return_allow, is_async),
         }
     }
 
@@ -2926,6 +3212,15 @@ fn lower_is_auto(&mut self, a: IsAuto) -> hir::IsAuto {
         }
     }
 
+    fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
+        hir::FnHeader {
+            unsafety: self.lower_unsafety(h.unsafety),
+            asyncness: self.lower_asyncness(h.asyncness),
+            constness: self.lower_constness(h.constness),
+            abi: h.abi,
+        }
+    }
+
     fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
         match u {
             Unsafety::Unsafe => hir::Unsafety::Unsafe,
@@ -2940,6 +3235,13 @@ fn lower_constness(&mut self, c: Spanned<Constness>) -> hir::Constness {
         }
     }
 
+    fn lower_asyncness(&mut self, a: IsAsync) -> hir::IsAsync {
+        match a {
+            IsAsync::Async(_) => hir::IsAsync::Async,
+            IsAsync::NotAsync => hir::IsAsync::NotAsync,
+        }
+    }
+
     fn lower_unop(&mut self, u: UnOp) -> hir::UnOp {
         match u {
             UnOp::Deref => hir::UnDeref,
@@ -3227,47 +3529,112 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 arms.iter().map(|x| self.lower_arm(x)).collect(),
                 hir::MatchSource::Normal,
             ),
-            ExprKind::Closure(capture_clause, movability, ref decl, ref body, fn_decl_span) => {
-                self.with_new_scopes(|this| {
-                    let mut is_generator = false;
-                    let body_id = this.lower_body(Some(decl), |this| {
-                        let e = this.lower_expr(body);
-                        is_generator = this.is_generator;
-                        e
-                    });
-                    let generator_option = if is_generator {
-                        if !decl.inputs.is_empty() {
-                            span_err!(
-                                this.sess,
-                                fn_decl_span,
-                                E0628,
-                                "generators cannot have explicit arguments"
-                            );
-                            this.sess.abort_if_errors();
-                        }
-                        Some(match movability {
-                            Movability::Movable => hir::GeneratorMovability::Movable,
-                            Movability::Static => hir::GeneratorMovability::Static,
-                        })
-                    } else {
-                        if movability == Movability::Static {
-                            span_err!(
+            ExprKind::Async(capture_clause, closure_node_id, ref block) => {
+                self.make_async_expr(capture_clause, closure_node_id, None, |this| {
+                    this.with_new_scopes(|this| {
+                        let block = this.lower_block(block, false);
+                        this.expr_block(block, ThinVec::new())
+                    })
+                })
+            }
+            ExprKind::Closure(
+                capture_clause, asyncness, movability, ref decl, ref body, fn_decl_span
+            ) => {
+                if let IsAsync::Async(async_closure_node_id) = asyncness {
+                    let outer_decl = FnDecl {
+                        inputs: decl.inputs.clone(),
+                        output: FunctionRetTy::Default(fn_decl_span),
+                        variadic: false,
+                    };
+                    // We need to lower the declaration outside the new scope, because we
+                    // have to conserve the state of being inside a loop condition for the
+                    // closure argument types.
+                    let fn_decl = self.lower_fn_decl(&outer_decl, None, false, false);
+
+                    self.with_new_scopes(|this| {
+                        // FIXME(cramertj) allow `async` non-`move` closures with
+                        if capture_clause == CaptureBy::Ref &&
+                            !decl.inputs.is_empty()
+                        {
+                            struct_span_err!(
                                 this.sess,
                                 fn_decl_span,
-                                E0697,
-                                "closures cannot be static"
-                            );
+                                E0708,
+                                "`async` non-`move` closures with arguments \
+                                are not currently supported",
+                            )
+                                .help("consider using `let` statements to manually capture \
+                                        variables by reference before entering an \
+                                        `async move` closure")
+                                .emit();
                         }
-                        None
-                    };
-                    hir::ExprClosure(
-                        this.lower_capture_clause(capture_clause),
-                        this.lower_fn_decl(decl, None, false),
-                        body_id,
-                        fn_decl_span,
-                        generator_option,
-                    )
-                })
+
+                        // Transform `async |x: u8| -> X { ... }` into
+                        // `|x: u8| future_from_generator(|| -> X { ... })`
+                        let body_id = this.lower_body(Some(&outer_decl), |this| {
+                            let async_ret_ty = if let FunctionRetTy::Ty(ty) = &decl.output {
+                                Some(&**ty)
+                            } else { None };
+                            let async_body = this.make_async_expr(
+                                capture_clause, async_closure_node_id, async_ret_ty,
+                                |this| {
+                                    this.with_new_scopes(|this| this.lower_expr(body))
+                                });
+                            this.expr(fn_decl_span, async_body, ThinVec::new())
+                        });
+                        hir::ExprClosure(
+                            this.lower_capture_clause(capture_clause),
+                            fn_decl,
+                            body_id,
+                            fn_decl_span,
+                            None,
+                        )
+                    })
+                } else {
+                    // Lower outside new scope to preserve `is_in_loop_condition`.
+                    let fn_decl = self.lower_fn_decl(decl, None, false, false);
+
+                    self.with_new_scopes(|this| {
+                        let mut is_generator = false;
+                        let body_id = this.lower_body(Some(decl), |this| {
+                            let e = this.lower_expr(body);
+                            is_generator = this.is_generator;
+                            e
+                        });
+                        let generator_option = if is_generator {
+                            if !decl.inputs.is_empty() {
+                                span_err!(
+                                    this.sess,
+                                    fn_decl_span,
+                                    E0628,
+                                    "generators cannot have explicit arguments"
+                                );
+                                this.sess.abort_if_errors();
+                            }
+                            Some(match movability {
+                                Movability::Movable => hir::GeneratorMovability::Movable,
+                                Movability::Static => hir::GeneratorMovability::Static,
+                            })
+                        } else {
+                            if movability == Movability::Static {
+                                span_err!(
+                                    this.sess,
+                                    fn_decl_span,
+                                    E0697,
+                                    "closures cannot be static"
+                                );
+                            }
+                            None
+                        };
+                        hir::ExprClosure(
+                            this.lower_capture_clause(capture_clause),
+                            fn_decl,
+                            body_id,
+                            fn_decl_span,
+                            generator_option,
+                        )
+                    })
+                }
             }
             ExprKind::Block(ref blk, opt_label) => {
                 hir::ExprBlock(self.lower_block(blk,
@@ -3293,7 +3660,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 let id = self.next_id();
                 let e1 = self.lower_expr(e1);
                 let e2 = self.lower_expr(e2);
-                let ty_path = P(self.std_path(span, &["ops", "RangeInclusive"], false));
+                let ty_path = P(self.std_path(span, &["ops", "RangeInclusive"], None, false));
                 let ty = self.ty_path(id, span, hir::QPath::Resolved(None, ty_path));
                 let new_seg = P(hir::PathSegment::from_name(Symbol::intern("new")));
                 let new_path = hir::QPath::TypeRelative(ty, new_seg);
@@ -3333,7 +3700,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 let struct_path = iter::once("ops")
                     .chain(iter::once(path))
                     .collect::<Vec<_>>();
-                let struct_path = self.std_path(unstable_span, &struct_path, is_unit);
+                let struct_path = self.std_path(unstable_span, &struct_path, None, is_unit);
                 let struct_path = hir::QPath::Resolved(None, P(struct_path));
 
                 let LoweredNodeId { node_id, hir_id } = self.lower_node_id(e.id);
@@ -3372,7 +3739,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 )
             }
             ExprKind::Continue(opt_label) => {
-                hir::ExprAgain(if self.is_in_loop_condition && opt_label.is_none() {
+                hir::ExprContinue(if self.is_in_loop_condition && opt_label.is_none() {
                     hir::Destination {
                         label: None,
                         target_id: Err(hir::LoopIdError::UnlabeledCfInWhileCondition).into(),
@@ -3610,7 +3977,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     let iter = P(self.expr_ident(head_sp, iter, iter_pat.id));
                     let ref_mut_iter = self.expr_mut_addr_of(head_sp, iter);
                     let next_path = &["iter", "Iterator", "next"];
-                    let next_path = P(self.expr_std_path(head_sp, next_path, ThinVec::new()));
+                    let next_path = P(self.expr_std_path(head_sp, next_path, None, ThinVec::new()));
                     let next_expr = P(self.expr_call(head_sp, next_path, hir_vec![ref_mut_iter]));
                     let arms = hir_vec![pat_arm, break_arm];
 
@@ -3668,7 +4035,8 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
                 let into_iter_expr = {
                     let into_iter_path = &["iter", "IntoIterator", "into_iter"];
-                    let into_iter = P(self.expr_std_path(head_sp, into_iter_path, ThinVec::new()));
+                    let into_iter = P(self.expr_std_path(
+                            head_sp, into_iter_path, None, ThinVec::new()));
                     P(self.expr_call(head_sp, into_iter, hir_vec![head]))
                 };
 
@@ -3714,7 +4082,8 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     let sub_expr = self.lower_expr(sub_expr);
 
                     let path = &["ops", "Try", "into_result"];
-                    let path = P(self.expr_std_path(unstable_span, path, ThinVec::new()));
+                    let path = P(self.expr_std_path(
+                            unstable_span, path, None, ThinVec::new()));
                     P(self.expr_call(e.span, path, hir_vec![sub_expr]))
                 };
 
@@ -3753,7 +4122,8 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     let err_local = self.pat_ident(e.span, err_ident);
                     let from_expr = {
                         let path = &["convert", "From", "from"];
-                        let from = P(self.expr_std_path(e.span, path, ThinVec::new()));
+                        let from = P(self.expr_std_path(
+                                e.span, path, None, ThinVec::new()));
                         let err_expr = self.expr_ident(e.span, err_ident, err_local.id);
 
                         self.expr_call(e.span, from, hir_vec![err_expr])
@@ -3993,9 +4363,10 @@ fn expr_std_path(
         &mut self,
         span: Span,
         components: &[&str],
+        params: Option<P<hir::GenericArgs>>,
         attrs: ThinVec<Attribute>,
     ) -> hir::Expr {
-        let path = self.std_path(span, components, true);
+        let path = self.std_path(span, components, params, true);
         self.expr(
             span,
             hir::ExprPath(hir::QPath::Resolved(None, P(path))),
@@ -4120,7 +4491,7 @@ fn pat_std_enum(
         components: &[&str],
         subpats: hir::HirVec<P<hir::Pat>>,
     ) -> P<hir::Pat> {
-        let path = self.std_path(span, components, true);
+        let path = self.std_path(span, components, None, true);
         let qpath = hir::QPath::Resolved(None, P(path));
         let pt = if subpats.is_empty() {
             hir::PatKind::Path(qpath)
@@ -4167,9 +4538,15 @@ fn pat(&mut self, span: Span, pat: hir::PatKind) -> P<hir::Pat> {
     /// Given suffix ["b","c","d"], returns path `::std::b::c::d` when
     /// `fld.cx.use_std`, and `::core::b::c::d` otherwise.
     /// The path is also resolved according to `is_value`.
-    fn std_path(&mut self, span: Span, components: &[&str], is_value: bool) -> hir::Path {
+    fn std_path(
+        &mut self,
+        span: Span,
+        components: &[&str],
+        params: Option<P<hir::GenericArgs>>,
+        is_value: bool
+    ) -> hir::Path {
         self.resolver
-            .resolve_str_path(span, self.crate_root, components, is_value)
+            .resolve_str_path(span, self.crate_root, components, params, is_value)
     }
 
     fn ty_path(&mut self, id: LoweredNodeId, span: Span, qpath: hir::QPath) -> P<hir::Ty> {
@@ -4217,7 +4594,7 @@ fn elided_ref_lifetime(&mut self, span: Span) -> hir::Lifetime {
                 hir::Lifetime {
                     id: self.next_id().node_id,
                     span,
-                    name: fresh_name,
+                    name: hir::LifetimeName::Param(fresh_name),
                 }
             }
 
@@ -4301,7 +4678,7 @@ fn wrap_in_try_constructor(
         unstable_span: Span,
     ) -> P<hir::Expr> {
         let path = &["ops", "Try", method];
-        let from_err = P(self.expr_std_path(unstable_span, path,
+        let from_err = P(self.expr_std_path(unstable_span, path, None,
                                             ThinVec::new()));
         P(self.expr_call(e.span, from_err, hir_vec![e]))
     }
index 362c0bf07f73bcb3c7ac54b060d036e58a59d6ec..f665ced3dbcf12de404a66590c2bab7e9b33d70c 100644 (file)
@@ -25,7 +25,6 @@
 use hir::map::{self, Node};
 use hir::{Expr, FnDecl};
 use hir::intravisit::FnKind;
-use rustc_target::spec::abi;
 use syntax::ast::{Attribute, Name, NodeId};
 use syntax_pos::Span;
 
@@ -105,9 +104,7 @@ pub fn from_node(map: &map::Map<'a>, id: NodeId) -> Option<Code<'a>> {
 struct ItemFnParts<'a> {
     name:     Name,
     decl:     &'a ast::FnDecl,
-    unsafety: ast::Unsafety,
-    constness: ast::Constness,
-    abi:      abi::Abi,
+    header:   ast::FnHeader,
     vis:      &'a ast::Visibility,
     generics: &'a ast::Generics,
     body:     ast::BodyId,
@@ -183,31 +180,31 @@ pub fn id(self) -> NodeId {
 
     pub fn constness(self) -> ast::Constness {
         match self.kind() {
-            FnKind::ItemFn(_, _, _, constness, ..) => {
-                constness
-            }
-            FnKind::Method(_, m, ..) => {
-                m.constness
-            }
+            FnKind::ItemFn(_, _, header, ..) => header.constness,
+            FnKind::Method(_, m, ..) => m.header.constness,
             _ => ast::Constness::NotConst
         }
     }
 
+    pub fn asyncness(self) -> ast::IsAsync {
+        match self.kind() {
+            FnKind::ItemFn(_, _, header, ..) => header.asyncness,
+            FnKind::Method(_, m, ..) => m.header.asyncness,
+            _ => ast::IsAsync::NotAsync
+        }
+    }
+
     pub fn unsafety(self) -> ast::Unsafety {
         match self.kind() {
-            FnKind::ItemFn(_, _, unsafety, ..) => {
-                unsafety
-            }
-            FnKind::Method(_, m, ..) => {
-                m.unsafety
-            }
+            FnKind::ItemFn(_, _, header, ..) => header.unsafety,
+            FnKind::Method(_, m, ..) => m.header.unsafety,
             _ => ast::Unsafety::Normal
         }
     }
 
     pub fn kind(self) -> FnKind<'a> {
         let item = |p: ItemFnParts<'a>| -> FnKind<'a> {
-            FnKind::ItemFn(p.name, p.generics, p.unsafety, p.constness, p.abi, p.vis, p.attrs)
+            FnKind::ItemFn(p.name, p.generics, p.header, p.vis, p.attrs)
         };
         let closure = |c: ClosureParts<'a>| {
             FnKind::Closure(c.attrs)
@@ -232,19 +229,17 @@ fn handle<A, I, M, C>(self, item_fn: I, method: M, closure: C) -> A where
     {
         match self.node {
             map::NodeItem(i) => match i.node {
-                ast::ItemFn(ref decl, unsafety, constness, abi, ref generics, block) =>
+                ast::ItemFn(ref decl, header, ref generics, block) =>
                     item_fn(ItemFnParts {
                         id: i.id,
                         name: i.name,
                         decl: &decl,
-                        unsafety,
                         body: block,
-                        generics,
-                        abi,
                         vis: &i.vis,
-                        constness,
                         span: i.span,
                         attrs: &i.attrs,
+                        header,
+                        generics,
                     }),
                 _ => bug!("item FnLikeNode that is not fn-like"),
             },
index 7835d4e782c430e86ad8231f98007a3833b53804..14cecba490d0ab3c99258ab9f7ab2429ce46d8f2 100644 (file)
@@ -212,7 +212,7 @@ fn insert(&mut self, id: NodeId, node: Node<'hir>) {
             NodeBlock(n) => EntryBlock(parent, dep_node_index, n),
             NodeStructCtor(n) => EntryStructCtor(parent, dep_node_index, n),
             NodeLifetime(n) => EntryLifetime(parent, dep_node_index, n),
-            NodeTyParam(n) => EntryTyParam(parent, dep_node_index, n),
+            NodeGenericParam(n) => EntryGenericParam(parent, dep_node_index, n),
             NodeVisibility(n) => EntryVisibility(parent, dep_node_index, n),
             NodeLocal(n) => EntryLocal(parent, dep_node_index, n),
             NodeMacroDef(n) => EntryMacroDef(dep_node_index, n),
@@ -347,14 +347,7 @@ fn visit_foreign_item(&mut self, foreign_item: &'hir ForeignItem) {
     }
 
     fn visit_generic_param(&mut self, param: &'hir GenericParam) {
-        match *param {
-            GenericParam::Lifetime(ref ld) => {
-                self.insert(ld.lifetime.id, NodeLifetime(&ld.lifetime));
-            }
-            GenericParam::Type(ref ty_param) => {
-                self.insert(ty_param.id, NodeTyParam(ty_param));
-            }
-        }
+        self.insert(param.id, NodeGenericParam(param));
         intravisit::walk_generic_param(self, param);
     }
 
index 48d959b4f8e4199552ebef77831731fbc39830f0..7c71401c8b2e8cbc6f54a734a70322ddcf9f303d 100644 (file)
@@ -73,6 +73,27 @@ pub fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F)
         self.parent_def = parent;
     }
 
+    fn visit_async_fn(
+        &mut self,
+        id: NodeId,
+        async_node_id: NodeId,
+        name: Name,
+        span: Span,
+        visit_fn: impl FnOnce(&mut DefCollector<'a>)
+    ) {
+        // For async functions, we need to create their inner defs inside of a
+        // closure to match their desugared representation.
+        let fn_def_data = DefPathData::ValueNs(name.as_interned_str());
+        let fn_def = self.create_def(id, fn_def_data, ITEM_LIKE_SPACE, span);
+        return self.with_parent(fn_def, |this| {
+            let closure_def = this.create_def(async_node_id,
+                                  DefPathData::ClosureExpr,
+                                  REGULAR_SPACE,
+                                  span);
+            this.with_parent(closure_def, visit_fn)
+        })
+    }
+
     fn visit_macro_invoc(&mut self, id: NodeId) {
         if let Some(ref mut visit) = self.visit_macro_invoc {
             visit(MacroInvocationData {
@@ -99,6 +120,15 @@ fn visit_item(&mut self, i: &'a Item) {
             ItemKind::Mod(..) if i.ident == keywords::Invalid.ident() => {
                 return visit::walk_item(self, i);
             }
+            ItemKind::Fn(_, FnHeader { asyncness: IsAsync::Async(async_node_id), .. }, ..) => {
+                return self.visit_async_fn(
+                    i.id,
+                    async_node_id,
+                    i.ident.name,
+                    i.span,
+                    |this| visit::walk_item(this, i)
+                )
+            }
             ItemKind::Mod(..) => DefPathData::Module(i.ident.name.as_interned_str()),
             ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
                 DefPathData::ValueNs(i.ident.name.as_interned_str()),
@@ -171,24 +201,12 @@ fn visit_variant_data(&mut self, data: &'a VariantData, _: Ident,
     }
 
     fn visit_generic_param(&mut self, param: &'a GenericParam) {
-        match *param {
-            GenericParam::Lifetime(ref lifetime_def) => {
-                self.create_def(
-                    lifetime_def.lifetime.id,
-                    DefPathData::LifetimeDef(lifetime_def.lifetime.ident.name.as_interned_str()),
-                    REGULAR_SPACE,
-                    lifetime_def.lifetime.ident.span
-                );
-            }
-            GenericParam::Type(ref ty_param) => {
-                self.create_def(
-                    ty_param.id,
-                    DefPathData::TypeParam(ty_param.ident.name.as_interned_str()),
-                    REGULAR_SPACE,
-                    ty_param.ident.span
-                );
-            }
-        }
+        let name = param.ident.name.as_interned_str();
+        let def_path_data = match param.kind {
+            GenericParamKind::Lifetime { .. } => DefPathData::LifetimeParam(name),
+            GenericParamKind::Type { .. } => DefPathData::TypeParam(name),
+        };
+        self.create_def(param.id, def_path_data, REGULAR_SPACE, param.ident.span);
 
         visit::walk_generic_param(self, param);
     }
@@ -209,6 +227,17 @@ 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(MethodSig {
+                header: FnHeader { asyncness: IsAsync::Async(async_node_id), .. }, ..
+            }, ..) => {
+                return self.visit_async_fn(
+                    ii.id,
+                    async_node_id,
+                    ii.ident.name,
+                    ii.span,
+                    |this| visit::walk_impl_item(this, ii)
+                )
+            }
             ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
                 DefPathData::ValueNs(ii.ident.name.as_interned_str()),
             ImplItemKind::Type(..) => DefPathData::AssocTypeInImpl(ii.ident.name.as_interned_str()),
@@ -239,15 +268,32 @@ fn visit_expr(&mut self, expr: &'a Expr) {
 
         match expr.node {
             ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id),
-            ExprKind::Closure(..) => {
-                let def = self.create_def(expr.id,
+            ExprKind::Closure(_, asyncness, ..) => {
+                let closure_def = self.create_def(expr.id,
                                           DefPathData::ClosureExpr,
                                           REGULAR_SPACE,
                                           expr.span);
-                self.parent_def = Some(def);
+                self.parent_def = Some(closure_def);
+
+                // Async closures desugar to closures inside of closures, so
+                // we must create two defs.
+                if let IsAsync::Async(async_id) = asyncness {
+                    let async_def = self.create_def(async_id,
+                                                    DefPathData::ClosureExpr,
+                                                    REGULAR_SPACE,
+                                                    expr.span);
+                    self.parent_def = Some(async_def);
+                }
+            }
+            ExprKind::Async(_, async_id, _) => {
+                let async_def = self.create_def(async_id,
+                                                DefPathData::ClosureExpr,
+                                                REGULAR_SPACE,
+                                                expr.span);
+                self.parent_def = Some(async_def);
             }
             _ => {}
-        }
+        };
 
         visit::walk_expr(self, expr);
         self.parent_def = parent_def;
index 99023a168674179cf37721c05f9362cbea53307f..b2365e22cc66f39268d0f4fc14a6af1cf16a14f8 100644 (file)
@@ -157,8 +157,13 @@ 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>,
+    /// If `Mark` is an ID of some macro expansion,
+    /// then `DefId` is the normal module (`mod`) in which the expanded macro was defined.
+    parent_modules_of_macro_defs: FxHashMap<Mark, DefId>,
+    /// Item with a given `DefIndex` was defined during opaque macro expansion with ID `Mark`.
+    /// It can actually be defined during transparent macro expansions inside that opaque expansion,
+    /// but transparent expansions are ignored here.
+    opaque_expansions_that_defined: FxHashMap<DefIndex, Mark>,
     next_disambiguator: FxHashMap<(DefIndex, DefPathData), u32>,
     def_index_to_span: FxHashMap<DefIndex, Span>,
 }
@@ -175,8 +180,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(),
+            parent_modules_of_macro_defs: self.parent_modules_of_macro_defs.clone(),
+            opaque_expansions_that_defined: self.opaque_expansions_that_defined.clone(),
             next_disambiguator: self.next_disambiguator.clone(),
             def_index_to_span: self.def_index_to_span.clone(),
         }
@@ -360,7 +365,7 @@ pub enum DefPathData {
     /// A type parameter (generic parameter)
     TypeParam(InternedString),
     /// A lifetime definition
-    LifetimeDef(InternedString),
+    LifetimeParam(InternedString),
     /// A variant of a enum
     EnumVariant(InternedString),
     /// A struct field
@@ -397,8 +402,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(),
+            parent_modules_of_macro_defs: FxHashMap(),
+            opaque_expansions_that_defined: FxHashMap(),
             next_disambiguator: FxHashMap(),
             def_index_to_span: FxHashMap(),
         }
@@ -580,7 +585,7 @@ pub fn create_def_with_parent(&mut self,
 
         let expansion = expansion.modern();
         if expansion != Mark::root() {
-            self.expansions.insert(index, expansion);
+            self.opaque_expansions_that_defined.insert(index, expansion);
         }
 
         // The span is added if it isn't DUMMY_SP
@@ -600,16 +605,16 @@ pub fn init_node_id_to_hir_id_mapping(&mut self,
         self.node_to_hir_id = mapping;
     }
 
-    pub fn expansion(&self, index: DefIndex) -> Mark {
-        self.expansions.get(&index).cloned().unwrap_or(Mark::root())
+    pub fn opaque_expansion_that_defined(&self, index: DefIndex) -> Mark {
+        self.opaque_expansions_that_defined.get(&index).cloned().unwrap_or(Mark::root())
     }
 
-    pub fn macro_def_scope(&self, mark: Mark) -> DefId {
-        self.macro_def_scopes[&mark]
+    pub fn parent_module_of_macro_def(&self, mark: Mark) -> DefId {
+        self.parent_modules_of_macro_defs[&mark]
     }
 
-    pub fn add_macro_def_scope(&mut self, mark: Mark, scope: DefId) {
-        self.macro_def_scopes.insert(mark, scope);
+    pub fn add_parent_module_of_macro_def(&mut self, mark: Mark, module: DefId) {
+        self.parent_modules_of_macro_defs.insert(mark, module);
     }
 }
 
@@ -625,7 +630,7 @@ pub fn get_opt_name(&self) -> Option<InternedString> {
             Module(name) |
             MacroDef(name) |
             TypeParam(name) |
-            LifetimeDef(name) |
+            LifetimeParam(name) |
             EnumVariant(name) |
             Field(name) |
             GlobalMetaData(name) => Some(name),
@@ -652,7 +657,7 @@ pub fn as_interned_str(&self) -> InternedString {
             Module(name) |
             MacroDef(name) |
             TypeParam(name) |
-            LifetimeDef(name) |
+            LifetimeParam(name) |
             EnumVariant(name) |
             Field(name) |
             GlobalMetaData(name) => {
index d2e04ef31c86afffe55638868b4cbd52ea1824c6..1e03381861b9b82d4ecc3f556385515dcd2a2aaa 100644 (file)
@@ -68,7 +68,7 @@ pub enum Node<'hir> {
     NodeStructCtor(&'hir VariantData),
 
     NodeLifetime(&'hir Lifetime),
-    NodeTyParam(&'hir TyParam),
+    NodeGenericParam(&'hir GenericParam),
     NodeVisibility(&'hir Visibility),
 }
 
@@ -96,7 +96,7 @@ enum MapEntry<'hir> {
     EntryBlock(NodeId, DepNodeIndex, &'hir Block),
     EntryStructCtor(NodeId, DepNodeIndex, &'hir VariantData),
     EntryLifetime(NodeId, DepNodeIndex, &'hir Lifetime),
-    EntryTyParam(NodeId, DepNodeIndex, &'hir TyParam),
+    EntryGenericParam(NodeId, DepNodeIndex, &'hir GenericParam),
     EntryVisibility(NodeId, DepNodeIndex, &'hir Visibility),
     EntryLocal(NodeId, DepNodeIndex, &'hir Local),
 
@@ -132,7 +132,7 @@ fn parent_node(self) -> Option<NodeId> {
             EntryBlock(id, _, _) => id,
             EntryStructCtor(id, _, _) => id,
             EntryLifetime(id, _, _) => id,
-            EntryTyParam(id, _, _) => id,
+            EntryGenericParam(id, _, _) => id,
             EntryVisibility(id, _, _) => id,
             EntryLocal(id, _, _) => id,
 
@@ -160,7 +160,7 @@ fn to_node(self) -> Option<Node<'hir>> {
             EntryBlock(_, _, n) => NodeBlock(n),
             EntryStructCtor(_, _, n) => NodeStructCtor(n),
             EntryLifetime(_, _, n) => NodeLifetime(n),
-            EntryTyParam(_, _, n) => NodeTyParam(n),
+            EntryGenericParam(_, _, n) => NodeGenericParam(n),
             EntryVisibility(_, _, n) => NodeVisibility(n),
             EntryLocal(_, _, n) => NodeLocal(n),
             EntryMacroDef(_, n) => NodeMacroDef(n),
@@ -174,7 +174,7 @@ fn fn_decl(&self) -> Option<&FnDecl> {
         match self {
             EntryItem(_, _, ref item) => {
                 match item.node {
-                    ItemFn(ref fn_decl, _, _, _, _, _) => Some(&fn_decl),
+                    ItemFn(ref fn_decl, _, _, _) => Some(&fn_decl),
                     _ => None,
                 }
             }
@@ -210,7 +210,7 @@ fn associated_body(self) -> Option<BodyId> {
                 match item.node {
                     ItemConst(_, body) |
                     ItemStatic(.., body) |
-                    ItemFn(_, _, _, _, _, body) => Some(body),
+                    ItemFn(_, _, _, body) => Some(body),
                     _ => None,
                 }
             }
@@ -328,7 +328,7 @@ pub fn read(&self, id: NodeId) {
             EntryBlock(_, dep_node_index, _) |
             EntryStructCtor(_, dep_node_index, _) |
             EntryLifetime(_, dep_node_index, _) |
-            EntryTyParam(_, dep_node_index, _) |
+            EntryGenericParam(_, dep_node_index, _) |
             EntryVisibility(_, dep_node_index, _) |
             EntryAnonConst(_, dep_node_index, _) |
             EntryExpr(_, dep_node_index, _) |
@@ -494,8 +494,11 @@ pub fn describe_def(&self, node_id: NodeId) -> Option<Def> {
                 Some(Def::Macro(self.local_def_id(macro_def.id),
                                 MacroKind::Bang))
             }
-            NodeTyParam(param) => {
-                Some(Def::TyParam(self.local_def_id(param.id)))
+            NodeGenericParam(param) => {
+                Some(match param.kind {
+                    GenericParamKind::Lifetime { .. } => Def::Local(param.id),
+                    GenericParamKind::Type { .. } => Def::TyParam(self.local_def_id(param.id)),
+                })
             }
         }
     }
@@ -600,7 +603,7 @@ pub fn body_owner_kind(&self, id: NodeId) -> BodyOwnerKind {
     pub fn ty_param_owner(&self, id: NodeId) -> NodeId {
         match self.get(id) {
             NodeItem(&Item { node: ItemTrait(..), .. }) => id,
-            NodeTyParam(_) => self.get_parent_node(id),
+            NodeGenericParam(_) => self.get_parent_node(id),
             _ => {
                 bug!("ty_param_owner: {} not a type parameter",
                     self.node_to_string(id))
@@ -613,11 +616,8 @@ pub fn ty_param_name(&self, id: NodeId) -> Name {
             NodeItem(&Item { node: ItemTrait(..), .. }) => {
                 keywords::SelfType.name()
             }
-            NodeTyParam(tp) => tp.name,
-            _ => {
-                bug!("ty_param_name: {} not a type parameter",
-                    self.node_to_string(id))
-            }
+            NodeGenericParam(param) => param.name.name(),
+            _ => bug!("ty_param_name: {} not a type parameter", self.node_to_string(id)),
         }
     }
 
@@ -954,7 +954,7 @@ pub fn name(&self, id: NodeId) -> Name {
             NodeVariant(v) => v.node.name,
             NodeField(f) => f.ident.name,
             NodeLifetime(lt) => lt.name.name(),
-            NodeTyParam(tp) => tp.name,
+            NodeGenericParam(param) => param.name.name(),
             NodeBinding(&Pat { node: PatKind::Binding(_,_,l,_), .. }) => l.node,
             NodeStructCtor(_) => self.name(self.get_parent(id)),
             _ => bug!("no name for {}", self.node_to_string(id))
@@ -974,7 +974,7 @@ pub fn attrs(&self, id: NodeId) -> &'hir [ast::Attribute] {
             Some(NodeField(ref f)) => Some(&f.attrs[..]),
             Some(NodeExpr(ref e)) => Some(&*e.attrs),
             Some(NodeStmt(ref s)) => Some(s.node.attrs()),
-            Some(NodeTyParam(tp)) => Some(&tp.attrs[..]),
+            Some(NodeGenericParam(param)) => Some(&param.attrs[..]),
             // unit/tuple structs take the attributes straight from
             // the struct definition.
             Some(NodeStructCtor(_)) => {
@@ -1021,7 +1021,7 @@ pub fn span(&self, id: NodeId) -> Span {
             Some(EntryBlock(_, _, block)) => block.span,
             Some(EntryStructCtor(_, _, _)) => self.expect_item(self.get_parent(id)).span,
             Some(EntryLifetime(_, _, lifetime)) => lifetime.span,
-            Some(EntryTyParam(_, _, ty_param)) => ty_param.span,
+            Some(EntryGenericParam(_, _, param)) => param.span,
             Some(EntryVisibility(_, _, &Visibility::Restricted { ref path, .. })) => path.span,
             Some(EntryVisibility(_, _, v)) => bug!("unexpected Visibility {:?}", v),
             Some(EntryLocal(_, _, local)) => local.span,
@@ -1226,19 +1226,19 @@ fn nested(&self, state: &mut print::State, nested: print::Nested) -> io::Result<
 impl<'a> print::State<'a> {
     pub fn print_node(&mut self, node: Node) -> io::Result<()> {
         match node {
-            NodeItem(a)        => self.print_item(&a),
-            NodeForeignItem(a) => self.print_foreign_item(&a),
-            NodeTraitItem(a)   => self.print_trait_item(a),
-            NodeImplItem(a)    => self.print_impl_item(a),
-            NodeVariant(a)     => self.print_variant(&a),
-            NodeAnonConst(a)   => self.print_anon_const(&a),
-            NodeExpr(a)        => self.print_expr(&a),
-            NodeStmt(a)        => self.print_stmt(&a),
-            NodeTy(a)          => self.print_type(&a),
-            NodeTraitRef(a)    => self.print_trait_ref(&a),
+            NodeItem(a)         => self.print_item(&a),
+            NodeForeignItem(a)  => self.print_foreign_item(&a),
+            NodeTraitItem(a)    => self.print_trait_item(a),
+            NodeImplItem(a)     => self.print_impl_item(a),
+            NodeVariant(a)      => self.print_variant(&a),
+            NodeAnonConst(a)    => self.print_anon_const(&a),
+            NodeExpr(a)         => self.print_expr(&a),
+            NodeStmt(a)         => self.print_stmt(&a),
+            NodeTy(a)           => self.print_type(&a),
+            NodeTraitRef(a)     => self.print_trait_ref(&a),
             NodeBinding(a)       |
-            NodePat(a)         => self.print_pat(&a),
-            NodeBlock(a)       => {
+            NodePat(a)          => self.print_pat(&a),
+            NodeBlock(a)        => {
                 use syntax::print::pprust::PrintState;
 
                 // containing cbox, will be closed by print-block at }
@@ -1247,16 +1247,16 @@ pub fn print_node(&mut self, node: Node) -> io::Result<()> {
                 self.ibox(0)?;
                 self.print_block(&a)
             }
-            NodeLifetime(a)    => self.print_lifetime(&a),
-            NodeVisibility(a)  => self.print_visibility(&a),
-            NodeTyParam(_)     => bug!("cannot print TyParam"),
-            NodeField(_)       => bug!("cannot print StructField"),
+            NodeLifetime(a)     => self.print_lifetime(&a),
+            NodeVisibility(a)   => self.print_visibility(&a),
+            NodeGenericParam(_) => bug!("cannot print NodeGenericParam"),
+            NodeField(_)        => bug!("cannot print StructField"),
             // these cases do not carry enough information in the
             // hir_map to reconstruct their full structure for pretty
             // printing.
-            NodeStructCtor(_)  => bug!("cannot print isolated StructCtor"),
-            NodeLocal(a)       => self.print_local_decl(&a),
-            NodeMacroDef(_)    => bug!("cannot print MacroDef"),
+            NodeStructCtor(_)   => bug!("cannot print isolated StructCtor"),
+            NodeLocal(a)        => self.print_local_decl(&a),
+            NodeMacroDef(_)     => bug!("cannot print MacroDef"),
         }
     }
 }
@@ -1371,8 +1371,8 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
         Some(NodeLifetime(_)) => {
             format!("lifetime {}{}", map.node_to_pretty_string(id), id_str)
         }
-        Some(NodeTyParam(ref ty_param)) => {
-            format!("typaram {:?}{}", ty_param, id_str)
+        Some(NodeGenericParam(ref param)) => {
+            format!("generic_param {:?}{}", param, id_str)
         }
         Some(NodeVisibility(ref vis)) => {
             format!("visibility {:?}{}", vis, id_str)
index 833090c3ee092342a836cad6eafdc9a059a9fd83..5f6921c7a87cc860d430b12f20f6fb10fae0474b 100644 (file)
@@ -22,7 +22,6 @@
 pub use self::PrimTy::*;
 pub use self::Stmt_::*;
 pub use self::Ty_::*;
-pub use self::TyParamBound::*;
 pub use self::UnOp::*;
 pub use self::UnsafeSource::*;
 pub use self::Visibility::{Public, Inherited};
@@ -53,8 +52,6 @@
 use serialize::{self, Encoder, Encodable, Decoder, Decodable};
 use std::collections::BTreeMap;
 use std::fmt;
-use std::iter;
-use std::slice;
 
 /// HIR doesn't commit to a concrete storage type and has its own alias for a vector.
 /// It can be `Vec`, `P<[T]>` or potentially `Box<[T]>`, or some other container with similar
@@ -203,12 +200,9 @@ pub struct Lifetime {
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
-pub enum LifetimeName {
-    /// User typed nothing. e.g. the lifetime in `&u32`.
-    Implicit,
-
-    /// User typed `'_`.
-    Underscore,
+pub enum ParamName {
+    /// Some user-given name like `T` or `'x`.
+    Plain(Name),
 
     /// Synthetic name generated when user elided a lifetime in an impl header,
     /// e.g. the lifetimes in cases like these:
@@ -224,12 +218,30 @@ pub enum LifetimeName {
     /// where `'f` is something like `Fresh(0)`. The indices are
     /// unique per impl, but not necessarily continuous.
     Fresh(usize),
+}
+
+impl ParamName {
+    pub fn name(&self) -> Name {
+        match *self {
+            ParamName::Plain(name) => name,
+            ParamName::Fresh(_) => keywords::UnderscoreLifetime.name(),
+        }
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
+pub enum LifetimeName {
+    /// User-given names or fresh (synthetic) names.
+    Param(ParamName),
+
+    /// User typed nothing. e.g. the lifetime in `&u32`.
+    Implicit,
+
+    /// User typed `'_`.
+    Underscore,
 
     /// User wrote `'static`
     Static,
-
-    /// Some user-given name like `'x`
-    Name(Name),
 }
 
 impl LifetimeName {
@@ -237,11 +249,29 @@ pub fn name(&self) -> Name {
         use self::LifetimeName::*;
         match *self {
             Implicit => keywords::Invalid.name(),
-            Fresh(_) | Underscore => keywords::UnderscoreLifetime.name(),
+            Underscore => keywords::UnderscoreLifetime.name(),
             Static => keywords::StaticLifetime.name(),
-            Name(name) => name,
+            Param(param_name) => param_name.name(),
+        }
+    }
+
+    pub fn is_elided(&self) -> bool {
+        use self::LifetimeName::*;
+        match self {
+            Implicit | Underscore => true,
+
+            // It might seem surprising that `Fresh(_)` counts as
+            // *not* elided -- but this is because, as far as the code
+            // in the compiler is concerned -- `Fresh(_)` variants act
+            // equivalently to "some fresh name". They correspond to
+            // early-bound regions on an impl, in other words.
+            Param(_) | Static => false,
         }
     }
+
+    fn is_static(&self) -> bool {
+        self == &LifetimeName::Static
+    }
 }
 
 impl fmt::Debug for Lifetime {
@@ -255,36 +285,14 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 impl Lifetime {
     pub fn is_elided(&self) -> bool {
-        use self::LifetimeName::*;
-        match self.name {
-            Implicit | Underscore => true,
-
-            // It might seem surprising that `Fresh(_)` counts as
-            // *not* elided -- but this is because, as far as the code
-            // in the compiler is concerned -- `Fresh(_)` variants act
-            // equivalently to "some fresh name". They correspond to
-            // early-bound regions on an impl, in other words.
-            Fresh(_) | Static | Name(_) => false,
-        }
+        self.name.is_elided()
     }
 
     pub fn is_static(&self) -> bool {
-        self.name == LifetimeName::Static
+        self.name.is_static()
     }
 }
 
-/// A lifetime definition, eg `'a: 'b+'c+'d`
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct LifetimeDef {
-    pub lifetime: Lifetime,
-    pub bounds: HirVec<Lifetime>,
-    pub pure_wrt_drop: bool,
-    // Indicates that the lifetime definition was synthetically added
-    // as a result of an in-band lifetime usage like
-    // `fn foo(x: &'a u8) -> &'a u8 { x }`
-    pub in_band: bool,
-}
-
 /// A "Path" is essentially Rust's notion of a name; for instance:
 /// `std::cmp::PartialEq`. It's represented as a sequence of identifiers,
 /// along with a bunch of supporting information.
@@ -327,7 +335,7 @@ pub struct PathSegment {
     /// this is more than just simple syntactic sugar; the use of
     /// parens affects the region binding rules, so we preserve the
     /// distinction.
-    pub parameters: Option<P<PathParameters>>,
+    pub args: Option<P<GenericArgs>>,
 
     /// Whether to infer remaining type parameters, if any.
     /// This only applies to expression and pattern paths, and
@@ -342,30 +350,30 @@ pub fn from_name(name: Name) -> PathSegment {
         PathSegment {
             name,
             infer_types: true,
-            parameters: None
+            args: None,
         }
     }
 
-    pub fn new(name: Name, parameters: PathParameters, infer_types: bool) -> Self {
+    pub fn new(name: Name, args: GenericArgs, infer_types: bool) -> Self {
         PathSegment {
             name,
             infer_types,
-            parameters: if parameters.is_empty() {
+            args: if args.is_empty() {
                 None
             } else {
-                Some(P(parameters))
+                Some(P(args))
             }
         }
     }
 
     // FIXME: hack required because you can't create a static
-    // PathParameters, so you can't just return a &PathParameters.
-    pub fn with_parameters<F, R>(&self, f: F) -> R
-        where F: FnOnce(&PathParameters) -> R
+    // GenericArgs, so you can't just return a &GenericArgs.
+    pub fn with_generic_args<F, R>(&self, f: F) -> R
+        where F: FnOnce(&GenericArgs) -> R
     {
-        let dummy = PathParameters::none();
-        f(if let Some(ref params) = self.parameters {
-            &params
+        let dummy = GenericArgs::none();
+        f(if let Some(ref args) = self.args {
+            &args
         } else {
             &dummy
         })
@@ -373,142 +381,114 @@ pub fn with_parameters<F, R>(&self, f: F) -> R
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct PathParameters {
-    /// The lifetime parameters for this path segment.
-    pub lifetimes: HirVec<Lifetime>,
-    /// The type parameters for this path segment, if present.
-    pub types: HirVec<P<Ty>>,
+pub enum GenericArg {
+    Lifetime(Lifetime),
+    Type(P<Ty>),
+}
+
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub struct GenericArgs {
+    /// The generic arguments for this path segment.
+    pub args: HirVec<GenericArg>,
     /// Bindings (equality constraints) on associated types, if present.
     /// E.g., `Foo<A=Bar>`.
     pub bindings: HirVec<TypeBinding>,
-    /// Were parameters written in parenthesized form `Fn(T) -> U`?
+    /// Were arguments written in parenthesized form `Fn(T) -> U`?
     /// This is required mostly for pretty-printing and diagnostics,
     /// but also for changing lifetime elision rules to be "function-like".
     pub parenthesized: bool,
 }
 
-impl PathParameters {
+impl GenericArgs {
     pub fn none() -> Self {
         Self {
-            lifetimes: HirVec::new(),
-            types: HirVec::new(),
+            args: HirVec::new(),
             bindings: HirVec::new(),
             parenthesized: false,
         }
     }
 
     pub fn is_empty(&self) -> bool {
-        self.lifetimes.is_empty() && self.types.is_empty() &&
-            self.bindings.is_empty() && !self.parenthesized
+        self.args.is_empty() && self.bindings.is_empty() && !self.parenthesized
     }
 
     pub fn inputs(&self) -> &[P<Ty>] {
         if self.parenthesized {
-            if let Some(ref ty) = self.types.get(0) {
-                if let TyTup(ref tys) = ty.node {
-                    return tys;
+            for arg in &self.args {
+                match arg {
+                    GenericArg::Lifetime(_) => {}
+                    GenericArg::Type(ref ty) => {
+                        if let TyTup(ref tys) = ty.node {
+                            return tys;
+                        }
+                        break;
+                    }
                 }
             }
         }
-        bug!("PathParameters::inputs: not a `Fn(T) -> U`");
+        bug!("GenericArgs::inputs: not a `Fn(T) -> U`");
     }
 }
 
+/// A modifier on a bound, currently this is only used for `?Sized`, where the
+/// modifier is `Maybe`. Negative bounds should also be handled here.
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum TraitBoundModifier {
+    None,
+    Maybe,
+}
+
 /// The AST represents all type param bounds as types.
 /// typeck::collect::compute_bounds matches these against
 /// the "special" built-in traits (see middle::lang_items) and
 /// detects Copy, Send and Sync.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum TyParamBound {
-    TraitTyParamBound(PolyTraitRef, TraitBoundModifier),
-    RegionTyParamBound(Lifetime),
+pub enum GenericBound {
+    Trait(PolyTraitRef, TraitBoundModifier),
+    Outlives(Lifetime),
 }
 
-impl TyParamBound {
+impl GenericBound {
     pub fn span(&self) -> Span {
         match self {
-            &TraitTyParamBound(ref t, ..) => t.span,
-            &RegionTyParamBound(ref l) => l.span,
+            &GenericBound::Trait(ref t, ..) => t.span,
+            &GenericBound::Outlives(ref l) => l.span,
         }
     }
 }
 
-/// A modifier on a bound, currently this is only used for `?Sized`, where the
-/// modifier is `Maybe`. Negative bounds should also be handled here.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum TraitBoundModifier {
-    None,
-    Maybe,
-}
+pub type GenericBounds = HirVec<GenericBound>;
 
-pub type TyParamBounds = HirVec<TyParamBound>;
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum GenericParamKind {
+    /// A lifetime definition, eg `'a: 'b + 'c + 'd`.
+    Lifetime {
+        // Indicates that the lifetime definition was synthetically added
+        // as a result of an in-band lifetime usage like:
+        // `fn foo(x: &'a u8) -> &'a u8 { x }`
+        in_band: bool,
+    },
+    Type {
+        default: Option<P<Ty>>,
+        synthetic: Option<SyntheticTyParamKind>,
+    }
+}
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct TyParam {
-    pub name: Name,
+pub struct GenericParam {
     pub id: NodeId,
-    pub bounds: TyParamBounds,
-    pub default: Option<P<Ty>>,
+    pub name: ParamName,
+    pub attrs: HirVec<Attribute>,
+    pub bounds: GenericBounds,
     pub span: Span,
     pub pure_wrt_drop: bool,
-    pub synthetic: Option<SyntheticTyParamKind>,
-    pub attrs: HirVec<Attribute>,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum GenericParam {
-    Lifetime(LifetimeDef),
-    Type(TyParam),
-}
-
-impl GenericParam {
-    pub fn is_lifetime_param(&self) -> bool {
-        match *self {
-            GenericParam::Lifetime(_) => true,
-            _ => false,
-        }
-    }
 
-    pub fn is_type_param(&self) -> bool {
-        match *self {
-            GenericParam::Type(_) => true,
-            _ => false,
-        }
-    }
+    pub kind: GenericParamKind,
 }
 
-pub trait GenericParamsExt {
-    fn lifetimes<'a>(&'a self) -> iter::FilterMap<
-        slice::Iter<GenericParam>,
-        fn(&GenericParam) -> Option<&LifetimeDef>,
-    >;
-
-    fn ty_params<'a>(&'a self) -> iter::FilterMap<
-        slice::Iter<GenericParam>,
-        fn(&GenericParam) -> Option<&TyParam>,
-    >;
-}
-
-impl GenericParamsExt for [GenericParam] {
-    fn lifetimes<'a>(&'a self) -> iter::FilterMap<
-        slice::Iter<GenericParam>,
-        fn(&GenericParam) -> Option<&LifetimeDef>,
-    > {
-        self.iter().filter_map(|param| match *param {
-            GenericParam::Lifetime(ref l) => Some(l),
-            _ => None,
-        })
-    }
-
-    fn ty_params<'a>(&'a self) -> iter::FilterMap<
-        slice::Iter<GenericParam>,
-        fn(&GenericParam) -> Option<&TyParam>,
-    > {
-        self.iter().filter_map(|param| match *param {
-            GenericParam::Type(ref t) => Some(t),
-            _ => None,
-        })
-    }
+pub struct GenericParamCount {
+    pub lifetimes: usize,
+    pub types: usize,
 }
 
 /// Represents lifetimes and type parameters attached to a declaration
@@ -532,55 +512,23 @@ pub fn empty() -> Generics {
         }
     }
 
-    pub fn is_lt_parameterized(&self) -> bool {
-        self.params.iter().any(|param| param.is_lifetime_param())
-    }
-
-    pub fn is_type_parameterized(&self) -> bool {
-        self.params.iter().any(|param| param.is_type_param())
-    }
-
-    pub fn lifetimes<'a>(&'a self) -> impl Iterator<Item = &'a LifetimeDef> {
-        self.params.lifetimes()
-    }
+    pub fn own_counts(&self) -> GenericParamCount {
+        // We could cache this as a property of `GenericParamCount`, but
+        // the aim is to refactor this away entirely eventually and the
+        // presence of this method will be a constant reminder.
+        let mut own_counts = GenericParamCount {
+            lifetimes: 0,
+            types: 0,
+        };
 
-    pub fn ty_params<'a>(&'a self) -> impl Iterator<Item = &'a TyParam> {
-        self.params.ty_params()
-    }
-}
-
-pub enum UnsafeGeneric {
-    Region(LifetimeDef, &'static str),
-    Type(TyParam, &'static str),
-}
-
-impl UnsafeGeneric {
-    pub fn attr_name(&self) -> &'static str {
-        match *self {
-            UnsafeGeneric::Region(_, s) => s,
-            UnsafeGeneric::Type(_, s) => s,
-        }
-    }
-}
-
-impl Generics {
-    pub fn carries_unsafe_attr(&self) -> Option<UnsafeGeneric> {
         for param in &self.params {
-            match *param {
-                GenericParam::Lifetime(ref l) => {
-                    if l.pure_wrt_drop {
-                        return Some(UnsafeGeneric::Region(l.clone(), "may_dangle"));
-                    }
-                }
-                GenericParam::Type(ref t) => {
-                    if t.pure_wrt_drop {
-                        return Some(UnsafeGeneric::Type(t.clone(), "may_dangle"));
-                    }
-                }
-            }
+            match param.kind {
+                GenericParamKind::Lifetime { .. } => own_counts.lifetimes += 1,
+                GenericParamKind::Type { .. } => own_counts.types += 1,
+            };
         }
 
-        None
+        own_counts
     }
 }
 
@@ -640,7 +588,7 @@ pub struct WhereBoundPredicate {
     /// The type being bounded
     pub bounded_ty: P<Ty>,
     /// Trait and lifetime bounds (`Clone+Send+'static`)
-    pub bounds: TyParamBounds,
+    pub bounds: GenericBounds,
 }
 
 /// A lifetime predicate, e.g. `'a: 'b+'c`
@@ -648,7 +596,7 @@ pub struct WhereBoundPredicate {
 pub struct WhereRegionPredicate {
     pub span: Span,
     pub lifetime: Lifetime,
-    pub bounds: HirVec<Lifetime>,
+    pub bounds: GenericBounds,
 }
 
 /// An equality predicate (unsupported), e.g. `T=int`
@@ -1331,7 +1279,7 @@ pub fn precedence(&self) -> ExprPrecedence {
             ExprPath(..) => ExprPrecedence::Path,
             ExprAddrOf(..) => ExprPrecedence::AddrOf,
             ExprBreak(..) => ExprPrecedence::Break,
-            ExprAgain(..) => ExprPrecedence::Continue,
+            ExprContinue(..) => ExprPrecedence::Continue,
             ExprRet(..) => ExprPrecedence::Ret,
             ExprInlineAsm(..) => ExprPrecedence::InlineAsm,
             ExprStruct(..) => ExprPrecedence::Struct,
@@ -1426,7 +1374,7 @@ pub enum Expr_ {
     /// A `break`, with an optional label to break
     ExprBreak(Destination, Option<P<Expr>>),
     /// A `continue`, with an optional label
-    ExprAgain(Destination),
+    ExprContinue(Destination),
     /// A `return`, with an optional value to be returned
     ExprRet(Option<P<Expr>>),
 
@@ -1558,9 +1506,7 @@ pub struct MutTy {
 /// Represents a method's signature in a trait declaration or implementation.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct MethodSig {
-    pub unsafety: Unsafety,
-    pub constness: Constness,
-    pub abi: Abi,
+    pub header: FnHeader,
     pub decl: P<FnDecl>,
 }
 
@@ -1607,7 +1553,7 @@ pub enum TraitItemKind {
     Method(MethodSig, TraitMethod),
     /// An associated type with (possibly empty) bounds and optional concrete
     /// type
-    Type(TyParamBounds, Option<P<Ty>>),
+    Type(GenericBounds, Option<P<Ty>>),
 }
 
 // The bodies for items are stored "out of line", in a separate
@@ -1692,7 +1638,7 @@ pub struct BareFnTy {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct ExistTy {
     pub generics: Generics,
-    pub bounds: TyParamBounds,
+    pub bounds: GenericBounds,
     pub impl_trait_fn: Option<DefId>,
 }
 
@@ -1788,7 +1734,13 @@ pub enum IsAuto {
     No
 }
 
-#[derive(Copy, Clone, PartialEq, Eq,PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum IsAsync {
+    Async,
+    NotAsync,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Unsafety {
     Unsafe,
     Normal,
@@ -2064,6 +2016,14 @@ pub struct Item {
     pub span: Span,
 }
 
+#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub struct FnHeader {
+    pub unsafety: Unsafety,
+    pub constness: Constness,
+    pub asyncness: IsAsync,
+    pub abi: Abi,
+}
+
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Item_ {
     /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
@@ -2083,7 +2043,7 @@ pub enum Item_ {
     /// A `const` item
     ItemConst(P<Ty>, BodyId),
     /// A function declaration
-    ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, BodyId),
+    ItemFn(P<FnDecl>, FnHeader, Generics, BodyId),
     /// A module
     ItemMod(Mod),
     /// An external module
@@ -2101,9 +2061,9 @@ pub enum Item_ {
     /// A union definition, e.g. `union Foo<A, B> {x: A, y: B}`
     ItemUnion(VariantData, Generics),
     /// Represents a Trait Declaration
-    ItemTrait(IsAuto, Unsafety, Generics, TyParamBounds, HirVec<TraitItemRef>),
+    ItemTrait(IsAuto, Unsafety, Generics, GenericBounds, HirVec<TraitItemRef>),
     /// Represents a Trait Alias Declaration
-    ItemTraitAlias(Generics, TyParamBounds),
+    ItemTraitAlias(Generics, GenericBounds),
 
     /// An implementation, eg `impl<A> Trait for Foo { .. }`
     ItemImpl(Unsafety,
@@ -2148,7 +2108,7 @@ pub fn adt_kind(&self) -> Option<AdtKind> {
 
     pub fn generics(&self) -> Option<&Generics> {
         Some(match *self {
-            ItemFn(_, _, _, _, ref generics, _) |
+            ItemFn(_, _, ref generics, _) |
             ItemTy(_, ref generics) |
             ItemEnum(_, ref generics) |
             ItemStruct(_, ref generics) |
index 1beef3f715e22098c8a50c33f131f590846a434a..6db4e987840bbb2b724e7008b8d07d354a15207c 100644 (file)
@@ -24,7 +24,8 @@
 use syntax_pos::{self, BytePos, FileName};
 
 use hir;
-use hir::{PatKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier, RangeEnd};
+use hir::{PatKind, GenericBound, TraitBoundModifier, RangeEnd};
+use hir::{GenericParam, GenericParamKind, GenericArg};
 
 use std::cell::Cell;
 use std::io::{self, Write, Read};
@@ -458,9 +459,12 @@ pub fn print_foreign_item(&mut self, item: &hir::ForeignItem) -> io::Result<()>
             hir::ForeignItemFn(ref decl, ref arg_names, ref generics) => {
                 self.head("")?;
                 self.print_fn(decl,
-                              hir::Unsafety::Normal,
-                              hir::Constness::NotConst,
-                              Abi::Rust,
+                              hir::FnHeader {
+                                  unsafety: hir::Unsafety::Normal,
+                                  constness: hir::Constness::NotConst,
+                                  abi: Abi::Rust,
+                                  asyncness: hir::IsAsync::NotAsync,
+                              },
                               Some(item.name),
                               generics,
                               &item.vis,
@@ -513,7 +517,7 @@ fn print_associated_const(&mut self,
 
     fn print_associated_type(&mut self,
                              name: ast::Name,
-                             bounds: Option<&hir::TyParamBounds>,
+                             bounds: Option<&hir::GenericBounds>,
                              ty: Option<&hir::Ty>)
                              -> io::Result<()> {
         self.word_space("type")?;
@@ -597,12 +601,10 @@ pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> {
                 self.s.word(";")?;
                 self.end()?; // end the outer cbox
             }
-            hir::ItemFn(ref decl, unsafety, constness, abi, ref typarams, body) => {
+            hir::ItemFn(ref decl, header, ref typarams, body) => {
                 self.head("")?;
                 self.print_fn(decl,
-                              unsafety,
-                              constness,
-                              abi,
+                              header,
                               Some(item.name),
                               typarams,
                               &item.vis,
@@ -661,7 +663,7 @@ pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> {
                 self.word_space(":")?;
                 let mut real_bounds = Vec::with_capacity(exist.bounds.len());
                 for b in exist.bounds.iter() {
-                    if let TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
+                    if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
                         self.s.space()?;
                         self.word_space("for ?")?;
                         self.print_trait_ref(&ptr.trait_ref)?;
@@ -739,7 +741,7 @@ pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> {
                 self.print_generic_params(&generics.params)?;
                 let mut real_bounds = Vec::with_capacity(bounds.len());
                 for b in bounds.iter() {
-                    if let TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
+                    if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
                         self.s.space()?;
                         self.word_space("for ?")?;
                         self.print_trait_ref(&ptr.trait_ref)?;
@@ -765,7 +767,7 @@ pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> {
                 let mut real_bounds = Vec::with_capacity(bounds.len());
                 // FIXME(durka) this seems to be some quite outdated syntax
                 for b in bounds.iter() {
-                    if let TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
+                    if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
                         self.s.space()?;
                         self.word_space("for ?")?;
                         self.print_trait_ref(&ptr.trait_ref)?;
@@ -934,9 +936,7 @@ pub fn print_method_sig(&mut self,
                             body_id: Option<hir::BodyId>)
                             -> io::Result<()> {
         self.print_fn(&m.decl,
-                      m.unsafety,
-                      m.constness,
-                      m.abi,
+                      m.header,
                       Some(name),
                       generics,
                       vis,
@@ -1268,15 +1268,11 @@ fn print_expr_method_call(&mut self,
         self.s.word(".")?;
         self.print_name(segment.name)?;
 
-        segment.with_parameters(|parameters| {
-            if !parameters.lifetimes.is_empty() ||
-                !parameters.types.is_empty() ||
-                !parameters.bindings.is_empty()
-            {
-                self.print_path_parameters(&parameters, segment.infer_types, true)
-            } else {
-                Ok(())
+        segment.with_generic_args(|generic_args| {
+            if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() {
+                return self.print_generic_args(&generic_args, segment.infer_types, true);
             }
+            Ok(())
         })?;
         self.print_call_post(base_args)
     }
@@ -1479,7 +1475,7 @@ pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> {
                     self.s.space()?;
                 }
             }
-            hir::ExprAgain(destination) => {
+            hir::ExprContinue(destination) => {
                 self.s.word("continue")?;
                 self.s.space()?;
                 if let Some(label) = destination.label {
@@ -1641,10 +1637,9 @@ pub fn print_path(&mut self,
             if segment.name != keywords::CrateRoot.name() &&
                segment.name != keywords::DollarCrate.name() {
                self.print_name(segment.name)?;
-               segment.with_parameters(|parameters| {
-                   self.print_path_parameters(parameters,
-                                              segment.infer_types,
-                                              colons_before_params)
+               segment.with_generic_args(|generic_args| {
+                   self.print_generic_args(generic_args, segment.infer_types,
+                                           colons_before_params)
                })?;
             }
         }
@@ -1673,10 +1668,10 @@ pub fn print_qpath(&mut self,
                     if segment.name != keywords::CrateRoot.name() &&
                        segment.name != keywords::DollarCrate.name() {
                         self.print_name(segment.name)?;
-                        segment.with_parameters(|parameters| {
-                            self.print_path_parameters(parameters,
-                                                       segment.infer_types,
-                                                       colons_before_params)
+                        segment.with_generic_args(|generic_args| {
+                            self.print_generic_args(generic_args,
+                                                    segment.infer_types,
+                                                    colons_before_params)
                         })?;
                     }
                 }
@@ -1685,10 +1680,10 @@ pub fn print_qpath(&mut self,
                 self.s.word("::")?;
                 let item_segment = path.segments.last().unwrap();
                 self.print_name(item_segment.name)?;
-                item_segment.with_parameters(|parameters| {
-                    self.print_path_parameters(parameters,
-                                               item_segment.infer_types,
-                                               colons_before_params)
+                item_segment.with_generic_args(|generic_args| {
+                    self.print_generic_args(generic_args,
+                                            item_segment.infer_types,
+                                            colons_before_params)
                 })
             }
             hir::QPath::TypeRelative(ref qself, ref item_segment) => {
@@ -1697,28 +1692,28 @@ pub fn print_qpath(&mut self,
                 self.s.word(">")?;
                 self.s.word("::")?;
                 self.print_name(item_segment.name)?;
-                item_segment.with_parameters(|parameters| {
-                    self.print_path_parameters(parameters,
-                                               item_segment.infer_types,
-                                               colons_before_params)
+                item_segment.with_generic_args(|generic_args| {
+                    self.print_generic_args(generic_args,
+                                            item_segment.infer_types,
+                                            colons_before_params)
                 })
             }
         }
     }
 
-    fn print_path_parameters(&mut self,
-                             parameters: &hir::PathParameters,
+    fn print_generic_args(&mut self,
+                             generic_args: &hir::GenericArgs,
                              infer_types: bool,
                              colons_before_params: bool)
                              -> io::Result<()> {
-        if parameters.parenthesized {
+        if generic_args.parenthesized {
             self.s.word("(")?;
-            self.commasep(Inconsistent, parameters.inputs(), |s, ty| s.print_type(&ty))?;
+            self.commasep(Inconsistent, generic_args.inputs(), |s, ty| s.print_type(&ty))?;
             self.s.word(")")?;
 
             self.space_if_not_bol()?;
             self.word_space("->")?;
-            self.print_type(&parameters.bindings[0].ty)?;
+            self.print_type(&generic_args.bindings[0].ty)?;
         } else {
             let start = if colons_before_params { "::<" } else { "<" };
             let empty = Cell::new(true);
@@ -1731,16 +1726,31 @@ fn print_path_parameters(&mut self,
                 }
             };
 
-            if !parameters.lifetimes.iter().all(|lt| lt.is_elided()) {
-                for lifetime in &parameters.lifetimes {
-                    start_or_comma(self)?;
-                    self.print_lifetime(lifetime)?;
+            let mut types = vec![];
+            let mut elide_lifetimes = true;
+            for arg in &generic_args.args {
+                match arg {
+                    GenericArg::Lifetime(lt) => {
+                        if !lt.is_elided() {
+                            elide_lifetimes = false;
+                        }
+                    }
+                    GenericArg::Type(ty) => {
+                        types.push(ty);
+                    }
                 }
             }
-
-            if !parameters.types.is_empty() {
+            if !elide_lifetimes {
+                start_or_comma(self)?;
+                self.commasep(Inconsistent, &generic_args.args, |s, generic_arg| {
+                    match generic_arg {
+                        GenericArg::Lifetime(lt) => s.print_lifetime(lt),
+                        GenericArg::Type(ty) => s.print_type(ty),
+                    }
+                })?;
+            } else if !types.is_empty() {
                 start_or_comma(self)?;
-                self.commasep(Inconsistent, &parameters.types, |s, ty| s.print_type(&ty))?;
+                self.commasep(Inconsistent, &types, |s, ty| s.print_type(&ty))?;
             }
 
             // FIXME(eddyb) This would leak into error messages, e.g.:
@@ -1750,7 +1760,7 @@ fn print_path_parameters(&mut self,
                 self.s.word("..")?;
             }
 
-            for binding in parameters.bindings.iter() {
+            for binding in generic_args.bindings.iter() {
                 start_or_comma(self)?;
                 self.print_name(binding.name)?;
                 self.s.space()?;
@@ -1975,16 +1985,14 @@ fn print_arm(&mut self, arm: &hir::Arm) -> io::Result<()> {
 
     pub fn print_fn(&mut self,
                     decl: &hir::FnDecl,
-                    unsafety: hir::Unsafety,
-                    constness: hir::Constness,
-                    abi: Abi,
+                    header: hir::FnHeader,
                     name: Option<ast::Name>,
                     generics: &hir::Generics,
                     vis: &hir::Visibility,
                     arg_names: &[Spanned<ast::Name>],
                     body_id: Option<hir::BodyId>)
                     -> io::Result<()> {
-        self.print_fn_header_info(unsafety, constness, abi, vis)?;
+        self.print_fn_header_info(header, vis)?;
 
         if let Some(name) = name {
             self.nbsp()?;
@@ -2060,7 +2068,7 @@ pub fn print_capture_clause(&mut self, capture_clause: hir::CaptureClause) -> io
         }
     }
 
-    pub fn print_bounds(&mut self, prefix: &str, bounds: &[hir::TyParamBound]) -> io::Result<()> {
+    pub fn print_bounds(&mut self, prefix: &str, bounds: &[hir::GenericBound]) -> io::Result<()> {
         if !bounds.is_empty() {
             self.s.word(prefix)?;
             let mut first = true;
@@ -2075,13 +2083,13 @@ pub fn print_bounds(&mut self, prefix: &str, bounds: &[hir::TyParamBound]) -> io
                 }
 
                 match bound {
-                    TraitTyParamBound(tref, modifier) => {
+                    GenericBound::Trait(tref, modifier) => {
                         if modifier == &TraitBoundModifier::Maybe {
                             self.s.word("?")?;
                         }
                         self.print_poly_trait_ref(tref)?;
                     }
-                    RegionTyParamBound(lt) => {
+                    GenericBound::Outlives(lt) => {
                         self.print_lifetime(lt)?;
                     }
                 }
@@ -2090,30 +2098,12 @@ pub fn print_bounds(&mut self, prefix: &str, bounds: &[hir::TyParamBound]) -> io
         Ok(())
     }
 
-    pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) -> io::Result<()> {
-        self.print_name(lifetime.name.name())
-    }
-
-    pub fn print_lifetime_def(&mut self, lifetime: &hir::LifetimeDef) -> io::Result<()> {
-        self.print_lifetime(&lifetime.lifetime)?;
-        let mut sep = ":";
-        for v in &lifetime.bounds {
-            self.s.word(sep)?;
-            self.print_lifetime(v)?;
-            sep = "+";
-        }
-        Ok(())
-    }
-
-    pub fn print_generic_params(&mut self, generic_params: &[hir::GenericParam]) -> io::Result<()> {
+    pub fn print_generic_params(&mut self, generic_params: &[GenericParam]) -> io::Result<()> {
         if !generic_params.is_empty() {
             self.s.word("<")?;
 
             self.commasep(Inconsistent, generic_params, |s, param| {
-                match *param {
-                    hir::GenericParam::Lifetime(ref ld) => s.print_lifetime_def(ld),
-                    hir::GenericParam::Type(ref tp) => s.print_ty_param(tp),
-                }
+                s.print_generic_param(param)
             })?;
 
             self.s.word(">")?;
@@ -2121,19 +2111,41 @@ pub fn print_generic_params(&mut self, generic_params: &[hir::GenericParam]) ->
         Ok(())
     }
 
-    pub fn print_ty_param(&mut self, param: &hir::TyParam) -> io::Result<()> {
-        self.print_name(param.name)?;
-        self.print_bounds(":", &param.bounds)?;
-        match param.default {
-            Some(ref default) => {
-                self.s.space()?;
-                self.word_space("=")?;
-                self.print_type(&default)
+    pub fn print_generic_param(&mut self, param: &GenericParam) -> io::Result<()> {
+        self.print_name(param.name.name())?;
+        match param.kind {
+            GenericParamKind::Lifetime { .. } => {
+                let mut sep = ":";
+                for bound in &param.bounds {
+                    match bound {
+                        GenericBound::Outlives(lt) => {
+                            self.s.word(sep)?;
+                            self.print_lifetime(lt)?;
+                            sep = "+";
+                        }
+                        _ => bug!(),
+                    }
+                }
+                Ok(())
+            }
+            GenericParamKind::Type { ref default, .. } => {
+                self.print_bounds(":", &param.bounds)?;
+                match default {
+                    Some(default) => {
+                        self.s.space()?;
+                        self.word_space("=")?;
+                        self.print_type(&default)
+                    }
+                    _ => Ok(()),
+                }
             }
-            _ => Ok(()),
         }
     }
 
+    pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) -> io::Result<()> {
+        self.print_name(lifetime.name.name())
+    }
+
     pub fn print_where_clause(&mut self, where_clause: &hir::WhereClause) -> io::Result<()> {
         if where_clause.predicates.is_empty() {
             return Ok(());
@@ -2165,7 +2177,12 @@ pub fn print_where_clause(&mut self, where_clause: &hir::WhereClause) -> io::Res
                     self.s.word(":")?;
 
                     for (i, bound) in bounds.iter().enumerate() {
-                        self.print_lifetime(bound)?;
+                        match bound {
+                            GenericBound::Outlives(lt) => {
+                                self.print_lifetime(lt)?;
+                            }
+                            _ => bug!(),
+                        }
 
                         if i != 0 {
                             self.s.word(":")?;
@@ -2240,9 +2257,12 @@ pub fn print_ty_fn(&mut self,
             span: syntax_pos::DUMMY_SP,
         };
         self.print_fn(decl,
-                      unsafety,
-                      hir::Constness::NotConst,
-                      abi,
+                      hir::FnHeader {
+                          unsafety,
+                          abi,
+                          constness: hir::Constness::NotConst,
+                          asyncness: hir::IsAsync::NotAsync,
+                      },
                       name,
                       &generics,
                       &hir::Inherited,
@@ -2313,22 +2333,26 @@ pub fn print_extern_opt_abi(&mut self, opt_abi: Option<Abi>) -> io::Result<()> {
     }
 
     pub fn print_fn_header_info(&mut self,
-                                unsafety: hir::Unsafety,
-                                constness: hir::Constness,
-                                abi: Abi,
+                                header: hir::FnHeader,
                                 vis: &hir::Visibility)
                                 -> io::Result<()> {
         self.s.word(&visibility_qualified(vis, ""))?;
-        self.print_unsafety(unsafety)?;
 
-        match constness {
+        match header.constness {
             hir::Constness::NotConst => {}
             hir::Constness::Const => self.word_nbsp("const")?,
         }
 
-        if abi != Abi::Rust {
+        match header.asyncness {
+            hir::IsAsync::NotAsync => {}
+            hir::IsAsync::Async => self.word_nbsp("async")?,
+        }
+
+        self.print_unsafety(header.unsafety)?;
+
+        if header.abi != Abi::Rust {
             self.word_nbsp("extern")?;
-            self.word_nbsp(&abi.to_string())?;
+            self.word_nbsp(&header.abi.to_string())?;
         }
 
         self.s.word("fn")
index ed259b2854511bd8c34eb994b0cc6a39ce990a4a..b71b69474a72051efee603b7bc5149a2bf6bf928 100644 (file)
@@ -142,12 +142,16 @@ fn hash_stable<W: StableHasherResult>(&self,
     }
 }
 
+impl_stable_hash_for!(enum hir::ParamName {
+    Plain(name),
+    Fresh(index)
+});
+
 impl_stable_hash_for!(enum hir::LifetimeName {
+    Param(param_name),
     Implicit,
     Underscore,
-    Fresh(index),
     Static,
-    Name(name)
 });
 
 impl_stable_hash_for!(struct hir::Label {
@@ -161,13 +165,6 @@ fn hash_stable<W: StableHasherResult>(&self,
     name
 });
 
-impl_stable_hash_for!(struct hir::LifetimeDef {
-    lifetime,
-    bounds,
-    pure_wrt_drop,
-    in_band
-});
-
 impl_stable_hash_for!(struct hir::Path {
     span,
     def,
@@ -177,19 +174,23 @@ fn hash_stable<W: StableHasherResult>(&self,
 impl_stable_hash_for!(struct hir::PathSegment {
     name,
     infer_types,
-    parameters
+    args
+});
+
+impl_stable_hash_for!(enum hir::GenericArg {
+    Lifetime(lt),
+    Type(ty)
 });
 
-impl_stable_hash_for!(struct hir::PathParameters {
-    lifetimes,
-    types,
+impl_stable_hash_for!(struct hir::GenericArgs {
+    args,
     bindings,
     parenthesized
 });
 
-impl_stable_hash_for!(enum hir::TyParamBound {
-    TraitTyParamBound(poly_trait_ref, trait_bound_modifier),
-    RegionTyParamBound(lifetime)
+impl_stable_hash_for!(enum hir::GenericBound {
+    Trait(poly_trait_ref, trait_bound_modifier),
+    Outlives(lifetime)
 });
 
 impl_stable_hash_for!(enum hir::TraitBoundModifier {
@@ -197,21 +198,32 @@ fn hash_stable<W: StableHasherResult>(&self,
     Maybe
 });
 
-impl_stable_hash_for!(struct hir::TyParam {
-    name,
+impl_stable_hash_for!(struct hir::GenericParam {
     id,
-    bounds,
-    default,
+    name,
     span,
     pure_wrt_drop,
-    synthetic,
-    attrs
+    attrs,
+    bounds,
+    kind
 });
 
-impl_stable_hash_for!(enum hir::GenericParam {
-    Lifetime(lifetime_def),
-    Type(ty_param)
-});
+impl<'a> HashStable<StableHashingContext<'a>> for hir::GenericParamKind {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match self {
+            hir::GenericParamKind::Lifetime { in_band } => {
+                in_band.hash_stable(hcx, hasher);
+            }
+            hir::GenericParamKind::Type { ref default, synthetic } => {
+                default.hash_stable(hcx, hasher);
+                synthetic.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
 
 impl_stable_hash_for!(struct hir::Generics {
     params,
@@ -260,9 +272,7 @@ fn hash_stable<W: StableHasherResult>(&self,
 });
 
 impl_stable_hash_for!(struct hir::MethodSig {
-    unsafety,
-    constness,
-    abi,
+    header,
     decl
 });
 
@@ -273,6 +283,13 @@ fn hash_stable<W: StableHasherResult>(&self,
     span
 });
 
+impl_stable_hash_for!(struct hir::FnHeader {
+    unsafety,
+    constness,
+    asyncness,
+    abi
+});
+
 impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
@@ -604,7 +621,7 @@ fn hash_stable<W: StableHasherResult>(&self,
     ExprPath(path),
     ExprAddrOf(mutability, sub),
     ExprBreak(destination, sub),
-    ExprAgain(destination),
+    ExprContinue(destination),
     ExprRet(val),
     ExprInlineAsm(asm, inputs, outputs),
     ExprStruct(path, fields, base),
@@ -885,7 +902,7 @@ fn hash_stable<W: StableHasherResult>(&self,
     ItemUse(path, use_kind),
     ItemStatic(ty, mutability, body_id),
     ItemConst(ty, body_id),
-    ItemFn(fn_decl, unsafety, constness, abi, generics, body_id),
+    ItemFn(fn_decl, header, generics, body_id),
     ItemMod(module),
     ItemForeignMod(foreign_mod),
     ItemGlobalAsm(global_asm),
@@ -1088,6 +1105,10 @@ fn hash_stable<W: StableHasherResult>(&self,
     Normal
 });
 
+impl_stable_hash_for!(enum hir::IsAsync {
+    Async,
+    NotAsync
+});
 
 impl_stable_hash_for!(enum hir::Constness {
     Const,
index 7b14831cf95c0d2c1e4920e165b1a6a074746735..935bc4c8c6d8c532e017942150cc4ad53fe38d56 100644 (file)
@@ -391,15 +391,11 @@ fn hash_token<'a, 'gcx, W: StableHasherResult>(
 
 impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo {
     call_site,
-    callee
-});
-
-impl_stable_hash_for!(struct ::syntax_pos::hygiene::NameAndSpan {
+    def_site,
     format,
     allow_internal_unstable,
     allow_internal_unsafe,
-    edition,
-    span
+    edition
 });
 
 impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnFormat {
@@ -409,6 +405,7 @@ fn hash_token<'a, 'gcx, W: StableHasherResult>(
 });
 
 impl_stable_hash_for!(enum ::syntax_pos::hygiene::CompilerDesugaringKind {
+    Async,
     DotFill,
     QuestionMark,
     ExistentialReturnType,
index 5e67065d1c13fcbf1656b29f3c2c54c596f55ac8..684a1d2965838e2bda85440abf9f9c3d63762bba 100644 (file)
@@ -1373,16 +1373,46 @@ impl<'tcx, R> for struct infer::canonical::QueryResult<'tcx, R> {
     Proven, Ambiguous
 });
 
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::WhereClauseAtom<'tcx> {
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::WhereClause<'tcx> {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
-        use traits::WhereClauseAtom::*;
+        use traits::WhereClause::*;
 
         mem::discriminant(self).hash_stable(hcx, hasher);
         match self {
             Implemented(trait_ref) => trait_ref.hash_stable(hcx, hasher),
             ProjectionEq(projection) => projection.hash_stable(hcx, hasher),
+            TypeOutlives(ty_outlives) => ty_outlives.hash_stable(hcx, hasher),
+            RegionOutlives(region_outlives) => region_outlives.hash_stable(hcx, hasher),
+        }
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::WellFormed<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a>,
+                                          hasher: &mut StableHasher<W>) {
+        use traits::WellFormed::*;
+
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match self {
+            Trait(trait_ref) => trait_ref.hash_stable(hcx, hasher),
+            Ty(ty) => ty.hash_stable(hcx, hasher),
+        }
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::FromEnv<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a>,
+                                          hasher: &mut StableHasher<W>) {
+        use traits::FromEnv::*;
+
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match self {
+            Trait(trait_ref) => trait_ref.hash_stable(hcx, hasher),
+            Ty(ty) => ty.hash_stable(hcx, hasher),
         }
     }
 }
@@ -1395,15 +1425,10 @@ fn hash_stable<W: StableHasherResult>(&self,
 
         mem::discriminant(self).hash_stable(hcx, hasher);
         match self {
-            Holds(where_clause) |
-            WellFormed(where_clause) |
-            FromEnv(where_clause) => where_clause.hash_stable(hcx, hasher),
-
-            WellFormedTy(ty) => ty.hash_stable(hcx, hasher),
+            Holds(wc) => wc.hash_stable(hcx, hasher),
+            WellFormed(wf) => wf.hash_stable(hcx, hasher),
+            FromEnv(from_env) => from_env.hash_stable(hcx, hasher),
             Normalize(projection) => projection.hash_stable(hcx, hasher),
-            FromEnvTy(ty) => ty.hash_stable(hcx, hasher),
-            RegionOutlives(predicate) => predicate.hash_stable(hcx, hasher),
-            TypeOutlives(predicate) => predicate.hash_stable(hcx, hasher),
         }
     }
 }
index f068a54ce44479f27a49ce8a1e49d9416f1da2e1..5487da97d5b2a137348e04041e0e11af62ebf484 100644 (file)
@@ -434,8 +434,8 @@ pub fn infer_anon_definition_from_instantiation(
         instantiated_ty: Ty<'gcx>,
     ) -> Ty<'gcx> {
         debug!(
-            "infer_anon_definition_from_instantiation(instantiated_ty={:?})",
-            instantiated_ty
+            "infer_anon_definition_from_instantiation(def_id={:?}, instantiated_ty={:?})",
+            def_id, instantiated_ty
         );
 
         let gcx = self.tcx.global_tcx();
index 1164c332330bc30d6bd0ad71532099517c1da44d..ef11cc0f4932e6094a238799cddd30d317ceca6a 100644 (file)
@@ -29,7 +29,7 @@
 //! For a more detailed look at what is happening here, check
 //! out the [chapter in the rustc guide][c].
 //!
-//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html
+//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
 
 use infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TypeVariableOrigin};
 use rustc_data_structures::indexed_vec::Idx;
@@ -274,7 +274,7 @@ pub fn fresh_inference_var_for_canonical_var(
     /// To get a good understanding of what is happening here, check
     /// out the [chapter in the rustc guide][c].
     ///
-    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html#processing-the-canonicalized-query-result
+    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#processing-the-canonicalized-query-result
     pub fn instantiate_query_result<R>(
         &self,
         cause: &ObligationCause<'tcx>,
@@ -458,7 +458,7 @@ fn unify_canonical_vars(
     /// To get a good understanding of what is happening here, check
     /// out the [chapter in the rustc guide][c].
     ///
-    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html#canonicalizing-the-query
+    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query
     pub fn canonicalize_query<V>(&self, value: &V) -> (V::Canonicalized, CanonicalVarValues<'tcx>)
     where
         V: Canonicalize<'gcx, 'tcx>,
@@ -497,7 +497,7 @@ pub fn canonicalize_query<V>(&self, value: &V) -> (V::Canonicalized, CanonicalVa
     /// To get a good understanding of what is happening here, check
     /// out the [chapter in the rustc guide][c].
     ///
-    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html#canonicalizing-the-query-result
+    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query-result
     pub fn canonicalize_response<V>(
         &self,
         value: &V,
index 4bde363672dcc68f4f08b845e4d75fe3dc0644b2..4d6f2fb41b05d7e5c5fa5512071b9aa2f9e0eacc 100644 (file)
@@ -1036,15 +1036,14 @@ pub fn report_generic_bound_failure(
                             // Get the `hir::TyParam` to verify whether it already has any bounds.
                             // We do this to avoid suggesting code that ends up as `T: 'a'b`,
                             // instead we suggest `T: 'a + 'b` in that case.
-                            let has_lifetimes = if let hir_map::NodeTyParam(ref p) = hir.get(id) {
-                                p.bounds.len() > 0
-                            } else {
-                                false
-                            };
+                            let mut has_bounds = false;
+                            if let hir_map::NodeGenericParam(ref param) = hir.get(id) {
+                                has_bounds = !param.bounds.is_empty();
+                            }
                             let sp = hir.span(id);
                             // `sp` only covers `T`, change it so that it covers
                             // `T:` when appropriate
-                            let sp = if has_lifetimes {
+                            let sp = if has_bounds {
                                 sp.to(self.tcx
                                     .sess
                                     .codemap()
@@ -1052,7 +1051,7 @@ pub fn report_generic_bound_failure(
                             } else {
                                 sp
                             };
-                            (sp, has_lifetimes)
+                            (sp, has_bounds)
                         })
                     } else {
                         None
index 680d445a1bcfcc6b169d405998178bc598df5250..43ed80b474ad5ebe4e2002f8d443012d5d57601e 100644 (file)
@@ -583,7 +583,7 @@ fn region_vars_confined_to_snapshot(&self,
     /// For more information about how skolemization for HRTBs works, see
     /// the [rustc guide].
     ///
-    /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html
+    /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/hrtb.html
     pub fn skolemize_late_bound_regions<T>(&self,
                                            binder: &ty::Binder<T>)
                                            -> (T, SkolemizationMap<'tcx>)
index 0086aed3e7c975b94b41d8b2646139b55be56dca..6e1c4191173bc8e44fae22c6b17f37b5d69cc46e 100644 (file)
@@ -3,7 +3,7 @@
 > WARNING: This README is obsolete and will be removed soon! For
 > more info on how the current borrowck works, see the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html
+[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
 
 ## Terminology
 
index 07b87e2012dde775df98f09d6c502d3ec8a8aed0..61603e6dee6866e7081232760b29c16fbfd73ee4 100644 (file)
@@ -3,7 +3,7 @@
 > WARNING: This README is obsolete and will be removed soon! For
 > more info on how the current borrowck works, see the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html
+[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
 
 ## Terminology
 
index 7d4a18c2a570b20f85d94fe4287738994eb041ba..a6bbd93750575cb3093e3f34ff7236f0a9ffc994 100644 (file)
     "detects name collision with an existing but unstable method"
 }
 
+declare_lint! {
+    pub IRREFUTABLE_LET_PATTERNS,
+    Deny,
+    "detects irrefutable patterns in if-let and while-let statements"
+}
+
 declare_lint! {
     pub UNUSED_LABELS,
     Allow,
     "warn about documentation intra links resolution failure"
 }
 
+declare_lint! {
+    pub WHERE_CLAUSES_OBJECT_SAFETY,
+    Warn,
+    "checks the object safety of where clauses"
+}
+
 /// Does nothing as a lint pass, but registers some `Lint`s
 /// which are used by other parts of the compiler.
 #[derive(Copy, Clone)]
@@ -355,9 +367,11 @@ fn get_lints(&self) -> LintArray {
             BARE_TRAIT_OBJECTS,
             ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
             UNSTABLE_NAME_COLLISIONS,
+            IRREFUTABLE_LET_PATTERNS,
             DUPLICATE_ASSOCIATED_TYPE_BINDINGS,
             DUPLICATE_MACRO_EXPORTS,
             INTRA_DOC_LINK_RESOLUTION_FAILURE,
+            WHERE_CLAUSES_OBJECT_SAFETY,
         )
     }
 }
index 9fb7d31ed6f75d178128989b8ed8f643da5afc47..718445bd3563e2908dc97ad53042a7122f7e56c1 100644 (file)
@@ -313,7 +313,8 @@ pub fn consume_body(&mut self, body: &hir::Body) {
         debug!("consume_body(body={:?})", body);
 
         for arg in &body.arguments {
-            let arg_ty = return_if_err!(self.mc.node_ty(arg.pat.hir_id));
+            let arg_ty = return_if_err!(self.mc.pat_ty_adjusted(&arg.pat));
+            debug!("consume_body: arg_ty = {:?}", arg_ty);
 
             let fn_body_scope_r =
                 self.tcx().mk_region(ty::ReScope(region::Scope::Node(body.value.hir_id.local_id)));
@@ -478,7 +479,7 @@ pub fn walk_expr(&mut self, expr: &hir::Expr) {
                 self.consume_exprs(inputs);
             }
 
-            hir::ExprAgain(..) |
+            hir::ExprContinue(..) |
             hir::ExprLit(..) => {}
 
             hir::ExprLoop(ref blk, _, _) => {
index 82686bc737bc818eb7a7dc2e9f9374164701acf0..b98a4416d213f32ce2c7a65c90154eab153ac7d4 100644 (file)
@@ -502,7 +502,7 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
       hir::ExprArray(..) | hir::ExprCall(..) | hir::ExprMethodCall(..) |
       hir::ExprTup(..) | hir::ExprBinary(..) | hir::ExprAddrOf(..) |
       hir::ExprCast(..) | hir::ExprUnary(..) | hir::ExprBreak(..) |
-      hir::ExprAgain(_) | hir::ExprLit(_) | hir::ExprRet(..) |
+      hir::ExprContinue(_) | hir::ExprLit(_) | hir::ExprRet(..) |
       hir::ExprBlock(..) | hir::ExprAssign(..) | hir::ExprAssignOp(..) |
       hir::ExprStruct(..) | hir::ExprRepeat(..) |
       hir::ExprInlineAsm(..) | hir::ExprBox(..) | hir::ExprYield(..) |
@@ -1047,7 +1047,7 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
               }
           }
 
-          hir::ExprAgain(label) => {
+          hir::ExprContinue(label) => {
               // Find which label this expr continues to
               let sc = match label.target_id {
                     Ok(node_id) => node_id,
@@ -1431,7 +1431,7 @@ fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) {
       hir::ExprIndex(..) | hir::ExprField(..) |
       hir::ExprArray(..) | hir::ExprTup(..) | hir::ExprBinary(..) |
       hir::ExprCast(..) | hir::ExprUnary(..) | hir::ExprRet(..) |
-      hir::ExprBreak(..) | hir::ExprAgain(..) | hir::ExprLit(_) |
+      hir::ExprBreak(..) | hir::ExprContinue(..) | hir::ExprLit(_) |
       hir::ExprBlock(..) | hir::ExprAddrOf(..) |
       hir::ExprStruct(..) | hir::ExprRepeat(..) |
       hir::ExprClosure(..) | hir::ExprPath(_) | hir::ExprYield(..) |
index 959dda69e30ed81d69ab2f88b9ab4e35adb45339..e3b59d25ab91f04c324bdfec65e91e93355cc03c 100644 (file)
@@ -517,7 +517,7 @@ pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
     ///   implicit deref patterns attached (e.g., it is really
     ///   `&Some(x)`). In that case, we return the "outermost" type
     ///   (e.g., `&Option<T>).
-    fn pat_ty(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
+    pub fn pat_ty_adjusted(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
         // Check for implicit `&` types wrapping the pattern; note
         // that these are never attached to binding patterns, so
         // actually this is somewhat "disjoint" from the code below
@@ -686,7 +686,7 @@ pub fn cat_expr_unadjusted(&self, expr: &hir::Expr) -> McResult<cmt_<'tcx>> {
           hir::ExprBinary(..) | hir::ExprWhile(..) |
           hir::ExprBlock(..) | hir::ExprLoop(..) | hir::ExprMatch(..) |
           hir::ExprLit(..) | hir::ExprBreak(..) |
-          hir::ExprAgain(..) | hir::ExprStruct(..) | hir::ExprRepeat(..) |
+          hir::ExprContinue(..) | hir::ExprStruct(..) | hir::ExprRepeat(..) |
           hir::ExprInlineAsm(..) | hir::ExprBox(..) => {
             Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty))
           }
@@ -1300,7 +1300,7 @@ fn cat_pattern_<F>(&self, mut cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McR
             };
 
             for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
-                let subpat_ty = self.pat_ty(&subpat)?; // see (*2)
+                let subpat_ty = self.pat_ty_adjusted(&subpat)?; // see (*2)
                 let interior = InteriorField(FieldIndex(i, Name::intern(&i.to_string())));
                 let subcmt = Rc::new(self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior));
                 self.cat_pattern_(subcmt, &subpat, op)?;
@@ -1323,7 +1323,7 @@ fn cat_pattern_<F>(&self, mut cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McR
             };
 
             for fp in field_pats {
-                let field_ty = self.pat_ty(&fp.node.pat)?; // see (*2)
+                let field_ty = self.pat_ty_adjusted(&fp.node.pat)?; // see (*2)
                 let f_index = self.tcx.field_index(fp.node.id, self.tables);
                 let cmt_field = Rc::new(self.cat_field(pat, cmt.clone(), f_index,
                                                        fp.node.ident, field_ty));
@@ -1342,7 +1342,7 @@ fn cat_pattern_<F>(&self, mut cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McR
                 ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty),
             };
             for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
-                let subpat_ty = self.pat_ty(&subpat)?; // see (*2)
+                let subpat_ty = self.pat_ty_unadjusted(&subpat)?; // see (*2)
                 let interior = InteriorField(FieldIndex(i, Name::intern(&i.to_string())));
                 let subcmt = Rc::new(self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior));
                 self.cat_pattern_(subcmt, &subpat, op)?;
index 40cf78edaecaebef9dd958c2f3bba0083c9bb510..95829346ede8ff07d009ec34c5c3c41530a7c688 100644 (file)
@@ -20,7 +20,7 @@
 use hir::def::Def;
 use hir::def_id::{DefId, CrateNum};
 use rustc_data_structures::sync::Lrc;
-use ty::{self, TyCtxt};
+use ty::{self, TyCtxt, GenericParamDefKind};
 use ty::query::Providers;
 use middle::privacy;
 use session::config;
 
 // Returns true if the given set of generics implies that the item it's
 // associated with must be inlined.
-fn generics_require_inlining(generics: &hir::Generics) -> bool {
-    generics.params.iter().any(|param| param.is_type_param())
+fn generics_require_inlining(generics: &ty::Generics) -> bool {
+    for param in &generics.params {
+        match param.kind {
+            GenericParamDefKind::Lifetime { .. } => {}
+            GenericParamDefKind::Type { .. } => return true,
+        }
+    }
+    false
 }
 
 // Returns true if the given item must be inlined because it may be
 // monomorphized or it was marked with `#[inline]`. This will only return
 // true for functions.
-fn item_might_be_inlined(item: &hir::Item, attrs: CodegenFnAttrs) -> bool {
+fn item_might_be_inlined(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                         item: &hir::Item,
+                         attrs: CodegenFnAttrs) -> bool {
     if attrs.requests_inline() {
         return true
     }
 
     match item.node {
-        hir::ItemImpl(_, _, _, ref generics, ..) |
-        hir::ItemFn(.., ref generics, _) => {
+        hir::ItemImpl(..) |
+        hir::ItemFn(..) => {
+            let generics = tcx.generics_of(tcx.hir.local_def_id(item.id));
             generics_require_inlining(generics)
         }
         _ => false,
@@ -62,14 +71,14 @@ fn method_might_be_inlined<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                      impl_item: &hir::ImplItem,
                                      impl_src: DefId) -> bool {
     let codegen_fn_attrs = tcx.codegen_fn_attrs(impl_item.hir_id.owner_def_id());
-    if codegen_fn_attrs.requests_inline() ||
-        generics_require_inlining(&impl_item.generics) {
+    let generics = tcx.generics_of(tcx.hir.local_def_id(impl_item.id));
+    if codegen_fn_attrs.requests_inline() || generics_require_inlining(generics) {
         return true
     }
     if let Some(impl_node_id) = tcx.hir.as_local_node_id(impl_src) {
         match tcx.hir.find(impl_node_id) {
             Some(hir_map::NodeItem(item)) =>
-                item_might_be_inlined(&item, codegen_fn_attrs),
+                item_might_be_inlined(tcx, &item, codegen_fn_attrs),
             Some(..) | None =>
                 span_bug!(impl_item.span, "impl did is not an item")
         }
@@ -163,7 +172,7 @@ fn def_id_represents_local_inlined_item(&self, def_id: DefId) -> bool {
             Some(hir_map::NodeItem(item)) => {
                 match item.node {
                     hir::ItemFn(..) =>
-                        item_might_be_inlined(&item, self.tcx.codegen_fn_attrs(def_id)),
+                        item_might_be_inlined(self.tcx, &item, self.tcx.codegen_fn_attrs(def_id)),
                     _ => false,
                 }
             }
@@ -180,7 +189,8 @@ fn def_id_represents_local_inlined_item(&self, def_id: DefId) -> bool {
                     hir::ImplItemKind::Const(..) => true,
                     hir::ImplItemKind::Method(..) => {
                         let attrs = self.tcx.codegen_fn_attrs(def_id);
-                        if generics_require_inlining(&impl_item.generics) ||
+                        let generics = self.tcx.generics_of(def_id);
+                        if generics_require_inlining(&generics) ||
                                 attrs.requests_inline() {
                             true
                         } else {
@@ -192,8 +202,9 @@ fn def_id_represents_local_inlined_item(&self, def_id: DefId) -> bool {
                             // does too.
                             let impl_node_id = self.tcx.hir.as_local_node_id(impl_did).unwrap();
                             match self.tcx.hir.expect_item(impl_node_id).node {
-                                hir::ItemImpl(_, _, _, ref generics, ..) => {
-                                    generics_require_inlining(generics)
+                                hir::ItemImpl(..) => {
+                                    let generics = self.tcx.generics_of(impl_did);
+                                    generics_require_inlining(&generics)
                                 }
                                 _ => false
                             }
@@ -227,8 +238,8 @@ fn propagate_node(&mut self, node: &hir_map::Node<'tcx>,
             // If we are building an executable, only explicitly extern
             // types need to be exported.
             if let hir_map::NodeItem(item) = *node {
-                let reachable = if let hir::ItemFn(.., abi, _, _) = item.node {
-                    abi != Abi::Rust
+                let reachable = if let hir::ItemFn(_, header, ..) = item.node {
+                    header.abi != Abi::Rust
                 } else {
                     false
                 };
@@ -251,7 +262,9 @@ fn propagate_node(&mut self, node: &hir_map::Node<'tcx>,
                 match item.node {
                     hir::ItemFn(.., body) => {
                         let def_id = self.tcx.hir.local_def_id(item.id);
-                        if item_might_be_inlined(&item, self.tcx.codegen_fn_attrs(def_id)) {
+                        if item_might_be_inlined(self.tcx,
+                                                 &item,
+                                                 self.tcx.codegen_fn_attrs(def_id)) {
                             self.visit_nested_body(body);
                         }
                     }
index e478f493647728e9cb50886c7bbba443d54fcc6f..c7249c0aa20c881ce5fb87cc113bc17d8720b928 100644 (file)
@@ -14,7 +14,7 @@
 //! For more information about how MIR-based region-checking works,
 //! see the [rustc guide].
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html
+//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
 
 use ich::{StableHashingContext, NodeIdHashingMode};
 use util::nodemap::{FxHashMap, FxHashSet};
index f251a3d5f38380ab42226b9041aff44cc228cce7..efb3eecd691f2dc47d3930af098c0b49166ff05b 100644 (file)
@@ -18,8 +18,7 @@
 use hir::def::Def;
 use hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
 use hir::map::Map;
-use hir::ItemLocalId;
-use hir::LifetimeName;
+use hir::{GenericArg, GenericParam, ItemLocalId, LifetimeName, ParamName};
 use ty::{self, TyCtxt, GenericParamDefKind};
 
 use errors::DiagnosticBuilder;
 use session::Session;
 use std::cell::Cell;
 use std::mem::replace;
-use std::slice;
 use syntax::ast;
 use syntax::attr;
 use syntax::ptr::P;
+use syntax::symbol::keywords;
 use syntax_pos::Span;
 use util::nodemap::{DefIdMap, FxHashMap, FxHashSet, NodeMap, NodeSet};
 
 use hir::intravisit::{self, NestedVisitorMap, Visitor};
-use hir::{self, GenericParamsExt};
+use hir::{self, GenericParamKind};
 
 /// The origin of a named lifetime definition.
 ///
@@ -50,11 +49,16 @@ pub enum LifetimeDefOrigin {
 }
 
 impl LifetimeDefOrigin {
-    fn from_is_in_band(is_in_band: bool) -> Self {
-        if is_in_band {
-            LifetimeDefOrigin::InBand
-        } else {
-            LifetimeDefOrigin::Explicit
+    fn from_param(param: &GenericParam) -> Self {
+        match param.kind {
+            GenericParamKind::Lifetime { in_band } => {
+                if in_band {
+                    LifetimeDefOrigin::InBand
+                } else {
+                    LifetimeDefOrigin::Explicit
+                }
+            }
+            _ => bug!("expected a lifetime param"),
         }
     }
 }
@@ -84,31 +88,27 @@ pub enum Region {
 }
 
 impl Region {
-    fn early(
-        hir_map: &Map,
-        index: &mut u32,
-        def: &hir::LifetimeDef,
-    ) -> (hir::LifetimeName, Region) {
+    fn early(hir_map: &Map, index: &mut u32, param: &GenericParam) -> (ParamName, Region) {
         let i = *index;
         *index += 1;
-        let def_id = hir_map.local_def_id(def.lifetime.id);
-        let origin = LifetimeDefOrigin::from_is_in_band(def.in_band);
+        let def_id = hir_map.local_def_id(param.id);
+        let origin = LifetimeDefOrigin::from_param(param);
         debug!("Region::early: index={} def_id={:?}", i, def_id);
-        (def.lifetime.name, Region::EarlyBound(i, def_id, origin))
+        (param.name, Region::EarlyBound(i, def_id, origin))
     }
 
-    fn late(hir_map: &Map, def: &hir::LifetimeDef) -> (hir::LifetimeName, Region) {
+    fn late(hir_map: &Map, param: &GenericParam) -> (ParamName, Region) {
         let depth = ty::INNERMOST;
-        let def_id = hir_map.local_def_id(def.lifetime.id);
-        let origin = LifetimeDefOrigin::from_is_in_band(def.in_band);
+        let def_id = hir_map.local_def_id(param.id);
+        let origin = LifetimeDefOrigin::from_param(param);
         debug!(
-            "Region::late: def={:?} depth={:?} def_id={:?} origin={:?}",
-            def,
+            "Region::late: param={:?} depth={:?} def_id={:?} origin={:?}",
+            param,
             depth,
             def_id,
             origin,
         );
-        (def.lifetime.name, Region::LateBound(depth, def_id, origin))
+        (param.name, Region::LateBound(depth, def_id, origin))
     }
 
     fn late_anon(index: &Cell<u32>) -> Region {
@@ -155,11 +155,10 @@ fn shifted_out_to_binder(self, binder: ty::DebruijnIndex) -> Region {
         }
     }
 
-    fn subst(self, params: &[hir::Lifetime], map: &NamedRegionMap) -> Option<Region> {
+    fn subst<'a, L>(self, mut params: L, map: &NamedRegionMap) -> Option<Region>
+            where L: Iterator<Item = &'a hir::Lifetime>  {
         if let Region::EarlyBound(index, _, _) = self {
-            params
-                .get(index as usize)
-                .and_then(|lifetime| map.defs.get(&lifetime.id).cloned())
+            params.nth(index as usize).and_then(|lifetime| map.defs.get(&lifetime.id).cloned())
         } else {
             Some(self)
         }
@@ -270,7 +269,7 @@ enum Scope<'a> {
     /// it should be shifted by the number of `Binder`s in between the
     /// declaration `Binder` and the location it's referenced from.
     Binder {
-        lifetimes: FxHashMap<hir::LifetimeName, Region>,
+        lifetimes: FxHashMap<hir::ParamName, Region>,
 
         /// if we extend this scope with another scope, what is the next index
         /// we should use for an early-bound region?
@@ -477,7 +476,7 @@ fn visit_nested_body(&mut self, body: hir::BodyId) {
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         match item.node {
-            hir::ItemFn(ref decl, _, _, _, ref generics, _) => {
+            hir::ItemFn(ref decl, _, ref generics, _) => {
                 self.visit_early_late(None, decl, generics, |this| {
                     intravisit::walk_item(this, item);
                 });
@@ -524,14 +523,19 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                 } else {
                     0
                 };
-                let lifetimes = generics
-                    .lifetimes()
-                    .map(|def| Region::early(&self.tcx.hir, &mut index, def))
-                    .collect();
-                let next_early_index = index + generics.ty_params().count() as u32;
+                let mut type_count = 0;
+                let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+                    GenericParamKind::Lifetime { .. } => {
+                        Some(Region::early(&self.tcx.hir, &mut index, param))
+                    }
+                    GenericParamKind::Type { .. } => {
+                        type_count += 1;
+                        None
+                    }
+                }).collect();
                 let scope = Scope::Binder {
                     lifetimes,
-                    next_early_index,
+                    next_early_index: index + type_count,
                     abstract_type_parent: true,
                     track_lifetime_uses,
                     s: ROOT_SCOPE,
@@ -568,10 +572,12 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
                 let was_in_fn_syntax = self.is_in_fn_syntax;
                 self.is_in_fn_syntax = true;
                 let scope = Scope::Binder {
-                    lifetimes: c.generic_params
-                        .lifetimes()
-                        .map(|def| Region::late(&self.tcx.hir, def))
-                        .collect(),
+                    lifetimes: c.generic_params.iter().filter_map(|param| match param.kind {
+                        GenericParamKind::Lifetime { .. } => {
+                            Some(Region::late(&self.tcx.hir, param))
+                        }
+                        _ => None,
+                    }).collect(),
                     s: self.scope,
                     next_early_index,
                     track_lifetime_uses: true,
@@ -603,9 +609,9 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
                         // resolved the same as the `'_` in `&'_ Foo`.
                         //
                         // cc #48468
-                        self.resolve_elided_lifetimes(slice::from_ref(lifetime), false)
+                        self.resolve_elided_lifetimes(vec![lifetime], false)
                     }
-                    LifetimeName::Fresh(_) | LifetimeName::Static | LifetimeName::Name(_) => {
+                    LifetimeName::Param(_) | LifetimeName::Static => {
                         // If the user wrote an explicit name, use that.
                         self.visit_lifetime(lifetime);
                     }
@@ -632,8 +638,8 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
                     // and ban them. Type variables instantiated inside binders aren't
                     // well-supported at the moment, so this doesn't work.
                     // In the future, this should be fixed and this error should be removed.
-                    let def = self.map.defs.get(&lifetime.id);
-                    if let Some(&Region::LateBound(_, def_id, _)) = def {
+                    let def = self.map.defs.get(&lifetime.id).cloned();
+                    if let Some(Region::LateBound(_, def_id, _)) = def {
                         if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
                             // Ensure that the parent of the def is an item, not HRTB
                             let parent_id = self.tcx.hir.get_parent_node(node_id);
@@ -651,6 +657,7 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
                                     "`impl Trait` can only capture lifetimes \
                                      bound at the fn or impl level"
                                 );
+                                self.uninsert_lifetime_on_error(lifetime, def.unwrap());
                             }
                         }
                     }
@@ -676,18 +683,29 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
 
                 let mut elision = None;
                 let mut lifetimes = FxHashMap();
-                for lt_def in generics.lifetimes() {
-                    let (lt_name, region) = Region::early(&self.tcx.hir, &mut index, &lt_def);
-                    if let hir::LifetimeName::Underscore = lt_name {
-                        // Pick the elided lifetime "definition" if one exists and use it to make
-                        // an elision scope.
-                        elision = Some(region);
-                    } else {
-                        lifetimes.insert(lt_name, region);
+                let mut type_count = 0;
+                for param in &generics.params {
+                    match param.kind {
+                        GenericParamKind::Lifetime { .. } => {
+                            let (name, reg) = Region::early(&self.tcx.hir, &mut index, &param);
+                            if let hir::ParamName::Plain(param_name) = name {
+                                if param_name == keywords::UnderscoreLifetime.name() {
+                                    // Pick the elided lifetime "definition" if one exists
+                                    // and use it to make an elision scope.
+                                    elision = Some(reg);
+                                } else {
+                                    lifetimes.insert(name, reg);
+                                }
+                            } else {
+                                lifetimes.insert(name, reg);
+                            }
+                        }
+                        GenericParamKind::Type { .. } => {
+                            type_count += 1;
+                        }
                     }
                 }
-
-                let next_early_index = index + generics.ty_params().count() as u32;
+                let next_early_index = index + type_count;
 
                 if let Some(elision_region) = elision {
                     let scope = Scope::Elision {
@@ -705,7 +723,7 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
                         this.with(scope, |_old_scope, this| {
                             this.visit_generics(generics);
                             for bound in bounds {
-                                this.visit_ty_param_bound(bound);
+                                this.visit_param_bound(bound);
                             }
                         });
                     });
@@ -720,7 +738,7 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
                     self.with(scope, |_old_scope, this| {
                         this.visit_generics(generics);
                         for bound in bounds {
-                            this.visit_ty_param_bound(bound);
+                            this.visit_param_bound(bound);
                         }
                     });
                 }
@@ -745,15 +763,19 @@ fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
                 let generics = &trait_item.generics;
                 let mut index = self.next_early_index();
                 debug!("visit_ty: index = {}", index);
-                let lifetimes = generics
-                    .lifetimes()
-                    .map(|lt_def| Region::early(&self.tcx.hir, &mut index, lt_def))
-                    .collect();
-
-                let next_early_index = index + generics.ty_params().count() as u32;
+                let mut type_count = 0;
+                let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+                    GenericParamKind::Lifetime { .. } => {
+                        Some(Region::early(&self.tcx.hir, &mut index, param))
+                    }
+                    GenericParamKind::Type { .. } => {
+                        type_count += 1;
+                        None
+                    }
+                }).collect();
                 let scope = Scope::Binder {
                     lifetimes,
-                    next_early_index,
+                    next_early_index: index + type_count,
                     s: self.scope,
                     track_lifetime_uses: true,
                     abstract_type_parent: true,
@@ -761,7 +783,7 @@ fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
                 self.with(scope, |_old_scope, this| {
                     this.visit_generics(generics);
                     for bound in bounds {
-                        this.visit_ty_param_bound(bound);
+                        this.visit_param_bound(bound);
                     }
                     if let Some(ty) = ty {
                         this.visit_ty(ty);
@@ -791,13 +813,17 @@ fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
             Type(ref ty) => {
                 let generics = &impl_item.generics;
                 let mut index = self.next_early_index();
+                let mut next_early_index = index;
                 debug!("visit_ty: index = {}", index);
-                let lifetimes = generics
-                    .lifetimes()
-                    .map(|lt_def| Region::early(&self.tcx.hir, &mut index, lt_def))
-                    .collect();
-
-                let next_early_index = index + generics.ty_params().count() as u32;
+                let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+                    GenericParamKind::Lifetime { .. } => {
+                        Some(Region::early(&self.tcx.hir, &mut index, param))
+                    }
+                    GenericParamKind::Type { .. } => {
+                        next_early_index += 1;
+                        None
+                    }
+                }).collect();
                 let scope = Scope::Binder {
                     lifetimes,
                     next_early_index,
@@ -820,7 +846,7 @@ fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
 
     fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
         if lifetime_ref.is_elided() {
-            self.resolve_elided_lifetimes(slice::from_ref(lifetime_ref), false);
+            self.resolve_elided_lifetimes(vec![lifetime_ref], false);
             return;
         }
         if lifetime_ref.is_static() {
@@ -833,8 +859,8 @@ fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
     fn visit_path(&mut self, path: &'tcx hir::Path, _: ast::NodeId) {
         for (i, segment) in path.segments.iter().enumerate() {
             let depth = path.segments.len() - i - 1;
-            if let Some(ref parameters) = segment.parameters {
-                self.visit_segment_parameters(path.def, depth, parameters);
+            if let Some(ref args) = segment.args {
+                self.visit_segment_args(path.def, depth, args);
             }
         }
     }
@@ -848,14 +874,16 @@ fn visit_fn_decl(&mut self, fd: &'tcx hir::FnDecl) {
     }
 
     fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
-        check_mixed_explicit_and_in_band_defs(
-            self.tcx,
-            &generics.lifetimes().cloned().collect::<Vec<_>>(),
-        );
-        for ty_param in generics.ty_params() {
-            walk_list!(self, visit_ty_param_bound, &ty_param.bounds);
-            if let Some(ref ty) = ty_param.default {
-                self.visit_ty(&ty);
+        check_mixed_explicit_and_in_band_defs(self.tcx, &generics.params);
+        for param in &generics.params {
+            match param.kind {
+                GenericParamKind::Lifetime { .. } => {}
+                GenericParamKind::Type { ref default, .. } => {
+                    walk_list!(self, visit_param_bound, &param.bounds);
+                    if let Some(ref ty) = default {
+                        self.visit_ty(&ty);
+                    }
+                }
             }
         }
         for predicate in &generics.where_clause.predicates {
@@ -866,14 +894,18 @@ fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
                     ref bound_generic_params,
                     ..
                 }) => {
-                    if bound_generic_params.iter().any(|p| p.is_lifetime_param()) {
+                    let lifetimes: FxHashMap<_, _> = bound_generic_params.iter()
+                        .filter_map(|param| match param.kind {
+                            GenericParamKind::Lifetime { .. } => {
+                                Some(Region::late(&self.tcx.hir, param))
+                            }
+                            _ => None,
+                        }).collect();
+                    if !lifetimes.is_empty() {
                         self.trait_ref_hack = true;
                         let next_early_index = self.next_early_index();
                         let scope = Scope::Binder {
-                            lifetimes: bound_generic_params
-                                .lifetimes()
-                                .map(|def| Region::late(&self.tcx.hir, def))
-                                .collect(),
+                            lifetimes,
                             s: self.scope,
                             next_early_index,
                             track_lifetime_uses: true,
@@ -882,13 +914,13 @@ fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
                         let result = self.with(scope, |old_scope, this| {
                             this.check_lifetime_params(old_scope, &bound_generic_params);
                             this.visit_ty(&bounded_ty);
-                            walk_list!(this, visit_ty_param_bound, bounds);
+                            walk_list!(this, visit_param_bound, bounds);
                         });
                         self.trait_ref_hack = false;
                         result
                     } else {
                         self.visit_ty(&bounded_ty);
-                        walk_list!(self, visit_ty_param_bound, bounds);
+                        walk_list!(self, visit_param_bound, bounds);
                     }
                 }
                 &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
@@ -897,9 +929,7 @@ fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
                     ..
                 }) => {
                     self.visit_lifetime(lifetime);
-                    for bound in bounds {
-                        self.visit_lifetime(bound);
-                    }
+                    walk_list!(self, visit_param_bound, bounds);
                 }
                 &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
                     ref lhs_ty,
@@ -924,7 +954,10 @@ fn visit_poly_trait_ref(
             || trait_ref
                 .bound_generic_params
                 .iter()
-                .any(|p| p.is_lifetime_param())
+                .any(|param| match param.kind {
+                    GenericParamKind::Lifetime { .. } => true,
+                    _ => false,
+                })
         {
             if self.trait_ref_hack {
                 span_err!(
@@ -936,11 +969,13 @@ fn visit_poly_trait_ref(
             }
             let next_early_index = self.next_early_index();
             let scope = Scope::Binder {
-                lifetimes: trait_ref
-                    .bound_generic_params
-                    .lifetimes()
-                    .map(|def| Region::late(&self.tcx.hir, def))
-                    .collect(),
+                lifetimes: trait_ref.bound_generic_params.iter()
+                    .filter_map(|param| match param.kind {
+                        GenericParamKind::Lifetime { .. } => {
+                            Some(Region::late(&self.tcx.hir, param))
+                        }
+                        _ => None,
+                    }).collect(),
                 s: self.scope,
                 next_early_index,
                 track_lifetime_uses: true,
@@ -989,10 +1024,10 @@ fn original_lifetime(span: Span) -> Original {
         span: span,
     }
 }
-fn shadower_lifetime(l: &hir::Lifetime) -> Shadower {
+fn shadower_lifetime(param: &hir::GenericParam) -> Shadower {
     Shadower {
         kind: ShadowKind::Lifetime,
-        span: l.span,
+        span: param.span,
     }
 }
 
@@ -1007,23 +1042,27 @@ fn desc(&self) -> &'static str {
 
 fn check_mixed_explicit_and_in_band_defs(
     tcx: TyCtxt<'_, '_, '_>,
-    lifetime_defs: &[hir::LifetimeDef],
+    params: &P<[hir::GenericParam]>,
 ) {
-    let oob_def = lifetime_defs.iter().find(|lt| !lt.in_band);
-    let in_band_def = lifetime_defs.iter().find(|lt| lt.in_band);
-
-    if let (Some(oob_def), Some(in_band_def)) = (oob_def, in_band_def) {
+    let in_bands: Vec<_> = params.iter().filter_map(|param| match param.kind {
+        GenericParamKind::Lifetime { in_band, .. } => Some((in_band, param.span)),
+        _ => None,
+    }).collect();
+    let out_of_band = in_bands.iter().find(|(in_band, _)| !in_band);
+    let in_band = in_bands.iter().find(|(in_band, _)| *in_band);
+
+    if let (Some((_, out_of_band_span)), Some((_, in_band_span)))
+        = (out_of_band, in_band) {
         struct_span_err!(
             tcx.sess,
-            in_band_def.lifetime.span,
+            *in_band_span,
             E0688,
             "cannot mix in-band and explicit lifetime definitions"
         ).span_label(
-            in_band_def.lifetime.span,
+            *in_band_span,
             "in-band lifetime definition here",
-        )
-            .span_label(oob_def.lifetime.span, "explicit lifetime definition here")
-            .emit();
+        ).span_label(*out_of_band_span, "explicit lifetime definition here")
+        .emit();
     }
 }
 
@@ -1138,7 +1177,8 @@ fn check_if_label_shadows_lifetime(
                     ref lifetimes, s, ..
                 } => {
                     // FIXME (#24278): non-hygienic comparison
-                    if let Some(def) = lifetimes.get(&hir::LifetimeName::Name(label)) {
+                    let param_name = hir::ParamName::Plain(label);
+                    if let Some(def) = lifetimes.get(&param_name) {
                         let node_id = tcx.hir.as_local_node_id(def.id().unwrap()).unwrap();
 
                         signal_shadowing_problem(
@@ -1176,14 +1216,18 @@ fn compute_object_lifetime_defaults(
                         .map(|set| match *set {
                             Set1::Empty => "BaseDefault".to_string(),
                             Set1::One(Region::Static) => "'static".to_string(),
-                            Set1::One(Region::EarlyBound(i, _, _)) => generics
-                                .lifetimes()
-                                .nth(i as usize)
-                                .unwrap()
-                                .lifetime
-                                .name
-                                .name()
-                                .to_string(),
+                            Set1::One(Region::EarlyBound(mut i, _, _)) => {
+                                generics.params.iter().find_map(|param| match param.kind {
+                                        GenericParamKind::Lifetime { .. } => {
+                                            if i == 0 {
+                                                return Some(param.name.name().to_string());
+                                            }
+                                            i -= 1;
+                                            None
+                                        }
+                                        _ => None,
+                                    }).unwrap()
+                            }
                             Set1::One(_) => bug!(),
                             Set1::Many => "Ambiguous".to_string(),
                         })
@@ -1207,17 +1251,17 @@ fn object_lifetime_defaults_for_item(
     tcx: TyCtxt<'_, '_, '_>,
     generics: &hir::Generics,
 ) -> Vec<ObjectLifetimeDefault> {
-    fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::TyParamBound]) {
+    fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::GenericBound]) {
         for bound in bounds {
-            if let hir::RegionTyParamBound(ref lifetime) = *bound {
+            if let hir::GenericBound::Outlives(ref lifetime) = *bound {
                 set.insert(lifetime.name);
             }
         }
     }
 
-    generics
-        .ty_params()
-        .map(|param| {
+    generics.params.iter().filter_map(|param| match param.kind {
+        GenericParamKind::Lifetime { .. } => None,
+        GenericParamKind::Type { .. } => {
             let mut set = Set1::Empty;
 
             add_bounds(&mut set, &param.bounds);
@@ -1246,27 +1290,35 @@ fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::TyParamBound]) {
                 }
             }
 
-            match set {
+            Some(match set {
                 Set1::Empty => Set1::Empty,
                 Set1::One(name) => {
                     if name == hir::LifetimeName::Static {
                         Set1::One(Region::Static)
                     } else {
-                        generics
-                            .lifetimes()
-                            .enumerate()
-                            .find(|&(_, def)| def.lifetime.name == name)
-                            .map_or(Set1::Many, |(i, def)| {
-                                let def_id = tcx.hir.local_def_id(def.lifetime.id);
-                                let origin = LifetimeDefOrigin::from_is_in_band(def.in_band);
-                                Set1::One(Region::EarlyBound(i as u32, def_id, origin))
-                            })
+                        generics.params.iter().filter_map(|param| match param.kind {
+                            GenericParamKind::Lifetime { .. } => {
+                                Some((
+                                    param.id,
+                                    hir::LifetimeName::Param(param.name),
+                                    LifetimeDefOrigin::from_param(param),
+                                ))
+                            }
+                            _ => None,
+                        })
+                        .enumerate()
+                        .find(|&(_, (_, lt_name, _))| lt_name == name)
+                        .map_or(Set1::Many, |(i, (id, _, origin))| {
+                            let def_id = tcx.hir.local_def_id(id);
+                            Set1::One(Region::EarlyBound(i as u32, def_id, origin))
+                        })
                     }
                 }
                 Set1::Many => Set1::Many,
-            }
-        })
-        .collect()
+            })
+        }
+    })
+    .collect()
 }
 
 impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
@@ -1343,28 +1395,28 @@ fn check_uses_for_lifetimes_defined_by_scope(&mut self) {
                 lifetimeuseset
             );
             match lifetimeuseset {
-                Some(LifetimeUseSet::One(_)) => {
+                Some(LifetimeUseSet::One(lifetime)) => {
                     let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
                     debug!("node id first={:?}", node_id);
-                    if let hir::map::NodeLifetime(hir_lifetime) = self.tcx.hir.get(node_id) {
-                        let span = hir_lifetime.span;
-                        let id = hir_lifetime.id;
-                        debug!(
-                            "id ={:?} span = {:?} hir_lifetime = {:?}",
-                            node_id, span, hir_lifetime
+                    if let Some((id, span, name)) = match self.tcx.hir.get(node_id) {
+                        hir::map::NodeLifetime(hir_lifetime) => {
+                            Some((hir_lifetime.id, hir_lifetime.span, hir_lifetime.name.name()))
+                        }
+                        hir::map::NodeGenericParam(param) => {
+                            Some((param.id, param.span, param.name.name()))
+                        }
+                        _ => None,
+                    } {
+                        debug!("id = {:?} span = {:?} name = {:?}", node_id, span, name);
+                        let mut err = self.tcx.struct_span_lint_node(
+                            lint::builtin::SINGLE_USE_LIFETIMES,
+                            id,
+                            span,
+                            &format!("lifetime parameter `{}` only used once", name),
                         );
-
-                        self.tcx
-                            .struct_span_lint_node(
-                                lint::builtin::SINGLE_USE_LIFETIMES,
-                                id,
-                                span,
-                                &format!(
-                                    "lifetime parameter `{}` only used once",
-                                    hir_lifetime.name.name()
-                                ),
-                            )
-                            .emit();
+                        err.span_label(span, "this lifetime...");
+                        err.span_label(lifetime.span, "...is used only here");
+                        err.emit();
                     }
                 }
                 Some(LifetimeUseSet::Many) => {
@@ -1372,21 +1424,22 @@ fn check_uses_for_lifetimes_defined_by_scope(&mut self) {
                 }
                 None => {
                     let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
-                    if let hir::map::NodeLifetime(hir_lifetime) = self.tcx.hir.get(node_id) {
-                        let span = hir_lifetime.span;
-                        let id = hir_lifetime.id;
-
-                        self.tcx
-                            .struct_span_lint_node(
-                                lint::builtin::UNUSED_LIFETIMES,
-                                id,
-                                span,
-                                &format!(
-                                    "lifetime parameter `{}` never used",
-                                    hir_lifetime.name.name()
-                                ),
-                            )
-                            .emit();
+                    if let Some((id, span, name)) = match self.tcx.hir.get(node_id) {
+                        hir::map::NodeLifetime(hir_lifetime) => {
+                            Some((hir_lifetime.id, hir_lifetime.span, hir_lifetime.name.name()))
+                        }
+                        hir::map::NodeGenericParam(param) => {
+                            Some((param.id, param.span, param.name.name()))
+                        }
+                        _ => None,
+                    } {
+                        debug!("id ={:?} span = {:?} name = {:?}", node_id, span, name);
+                        self.tcx.struct_span_lint_node(
+                            lint::builtin::UNUSED_LIFETIMES,
+                            id,
+                            span,
+                            &format!("lifetime parameter `{}` never used", name)
+                        ).emit();
                     }
                 }
             }
@@ -1438,18 +1491,21 @@ fn visit_early_late<F>(
             }
         }
 
-        let lifetimes = generics
-            .lifetimes()
-            .map(|def| {
-                if self.map.late_bound.contains(&def.lifetime.id) {
-                    Region::late(&self.tcx.hir, def)
+        let mut type_count = 0;
+        let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+            GenericParamKind::Lifetime { .. } => {
+                if self.map.late_bound.contains(&param.id) {
+                    Some(Region::late(&self.tcx.hir, param))
                 } else {
-                    Region::early(&self.tcx.hir, &mut index, def)
+                    Some(Region::early(&self.tcx.hir, &mut index, param))
                 }
-            })
-            .collect();
-
-        let next_early_index = index + generics.ty_params().count() as u32;
+            }
+            GenericParamKind::Type { .. } => {
+                type_count += 1;
+                None
+            }
+        }).collect();
+        let next_early_index = index + type_count;
 
         let scope = Scope::Binder {
             lifetimes,
@@ -1521,10 +1577,12 @@ fn resolve_lifetime_ref(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
                     break None;
                 }
 
-                Scope::Binder {
-                    ref lifetimes, s, ..
-                } => {
-                    if let Some(&def) = lifetimes.get(&lifetime_ref.name) {
+                Scope::Binder { ref lifetimes, s, .. } => {
+                    let name = match lifetime_ref.name {
+                        LifetimeName::Param(param_name) => param_name,
+                        _ => bug!("expected LifetimeName::Param"),
+                    };
+                    if let Some(&def) = lifetimes.get(&name) {
                         break Some(def.shifted(late_depth));
                     } else {
                         late_depth += 1;
@@ -1599,26 +1657,35 @@ fn resolve_lifetime_ref(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
         }
     }
 
-    fn visit_segment_parameters(
+    fn visit_segment_args(
         &mut self,
         def: Def,
         depth: usize,
-        params: &'tcx hir::PathParameters,
+        generic_args: &'tcx hir::GenericArgs,
     ) {
-        if params.parenthesized {
+        if generic_args.parenthesized {
             let was_in_fn_syntax = self.is_in_fn_syntax;
             self.is_in_fn_syntax = true;
-            self.visit_fn_like_elision(params.inputs(), Some(&params.bindings[0].ty));
+            self.visit_fn_like_elision(generic_args.inputs(),
+                                       Some(&generic_args.bindings[0].ty));
             self.is_in_fn_syntax = was_in_fn_syntax;
             return;
         }
 
-        if params.lifetimes.iter().all(|l| l.is_elided()) {
-            self.resolve_elided_lifetimes(&params.lifetimes, true);
-        } else {
-            for l in &params.lifetimes {
-                self.visit_lifetime(l);
+        let mut elide_lifetimes = true;
+        let lifetimes = generic_args.args.iter().filter_map(|arg| match arg {
+            hir::GenericArg::Lifetime(lt) => {
+                if !lt.is_elided() {
+                    elide_lifetimes = false;
+                }
+                Some(lt)
             }
+            _ => None,
+        }).collect();
+        if elide_lifetimes {
+            self.resolve_elided_lifetimes(lifetimes, true);
+        } else {
+            lifetimes.iter().for_each(|lt| self.visit_lifetime(lt));
         }
 
         // Figure out if this is a type/trait segment,
@@ -1680,33 +1747,45 @@ fn visit_segment_parameters(
                         }).collect()
                     })
             };
-            unsubst
-                .iter()
-                .map(|set| match *set {
-                    Set1::Empty => if in_body {
-                        None
-                    } else {
-                        Some(Region::Static)
-                    },
-                    Set1::One(r) => r.subst(&params.lifetimes, map),
-                    Set1::Many => None,
-                })
-                .collect()
+            unsubst.iter()
+                   .map(|set| match *set {
+                       Set1::Empty => if in_body {
+                           None
+                       } else {
+                           Some(Region::Static)
+                       },
+                       Set1::One(r) => {
+                           let lifetimes = generic_args.args.iter().filter_map(|arg| match arg {
+                               GenericArg::Lifetime(lt) => Some(lt),
+                               _ => None,
+                           });
+                           r.subst(lifetimes, map)
+                       }
+                       Set1::Many => None,
+                   })
+                   .collect()
         });
 
-        for (i, ty) in params.types.iter().enumerate() {
-            if let Some(&lt) = object_lifetime_defaults.get(i) {
-                let scope = Scope::ObjectLifetimeDefault {
-                    lifetime: lt,
-                    s: self.scope,
-                };
-                self.with(scope, |_, this| this.visit_ty(ty));
-            } else {
-                self.visit_ty(ty);
+        let mut i = 0;
+        for arg in &generic_args.args {
+            match arg {
+                GenericArg::Lifetime(_) => {}
+                GenericArg::Type(ty) => {
+                    if let Some(&lt) = object_lifetime_defaults.get(i) {
+                        let scope = Scope::ObjectLifetimeDefault {
+                            lifetime: lt,
+                            s: self.scope,
+                        };
+                        self.with(scope, |_, this| this.visit_ty(ty));
+                    } else {
+                        self.visit_ty(ty);
+                    }
+                    i += 1;
+                }
             }
         }
 
-        for b in &params.bindings {
+        for b in &generic_args.bindings {
             self.visit_assoc_type_binding(b);
         }
     }
@@ -1944,7 +2023,7 @@ fn visit_ty(&mut self, ty: &hir::Ty) {
             }
 
             fn visit_generic_param(&mut self, param: &hir::GenericParam) {
-                if let hir::GenericParam::Lifetime(_) = *param {
+                if let hir::GenericParamKind::Lifetime { .. } = param.kind {
                     // FIXME(eddyb) Do we want this? It only makes a difference
                     // if this `for<'a>` lifetime parameter is never used.
                     self.have_bound_regions = true;
@@ -1981,7 +2060,9 @@ fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) {
         }
     }
 
-    fn resolve_elided_lifetimes(&mut self, lifetime_refs: &'tcx [hir::Lifetime], deprecated: bool) {
+    fn resolve_elided_lifetimes(&mut self,
+                                lifetime_refs: Vec<&'tcx hir::Lifetime>,
+                                deprecated: bool) {
         if lifetime_refs.is_empty() {
             return;
         }
@@ -2159,100 +2240,99 @@ fn resolve_object_lifetime_default(&mut self, lifetime_ref: &'tcx hir::Lifetime)
     }
 
     fn check_lifetime_params(&mut self, old_scope: ScopeRef, params: &'tcx [hir::GenericParam]) {
-        for (i, lifetime_i) in params.lifetimes().enumerate() {
-            match lifetime_i.lifetime.name {
-                hir::LifetimeName::Static | hir::LifetimeName::Underscore => {
-                    let lifetime = lifetime_i.lifetime;
-                    let name = lifetime.name.name();
+        let lifetimes: Vec<_> = params.iter().filter_map(|param| match param.kind {
+            GenericParamKind::Lifetime { .. } => Some((param, param.name)),
+            _ => None,
+        }).collect();
+        for (i, (lifetime_i, lifetime_i_name)) in lifetimes.iter().enumerate() {
+            if let hir::ParamName::Plain(_) = lifetime_i_name {
+                let name = lifetime_i_name.name();
+                if name == keywords::UnderscoreLifetime.name() ||
+                   name == keywords::StaticLifetime.name() {
                     let mut err = struct_span_err!(
                         self.tcx.sess,
-                        lifetime.span,
+                        lifetime_i.span,
                         E0262,
                         "invalid lifetime parameter name: `{}`",
                         name
                     );
                     err.span_label(
-                        lifetime.span,
+                        lifetime_i.span,
                         format!("{} is a reserved lifetime name", name),
                     );
                     err.emit();
                 }
-                hir::LifetimeName::Fresh(_)
-                | hir::LifetimeName::Implicit
-                | hir::LifetimeName::Name(_) => {}
             }
 
             // It is a hard error to shadow a lifetime within the same scope.
-            for lifetime_j in params.lifetimes().skip(i + 1) {
-                if lifetime_i.lifetime.name == lifetime_j.lifetime.name {
+            for (lifetime_j, lifetime_j_name) in lifetimes.iter().skip(i + 1) {
+                if lifetime_i_name == lifetime_j_name {
                     struct_span_err!(
                         self.tcx.sess,
-                        lifetime_j.lifetime.span,
+                        lifetime_j.span,
                         E0263,
                         "lifetime name `{}` declared twice in the same scope",
-                        lifetime_j.lifetime.name.name()
-                    ).span_label(lifetime_j.lifetime.span, "declared twice")
-                        .span_label(lifetime_i.lifetime.span, "previous declaration here")
-                        .emit();
+                        lifetime_j.name.name()
+                    ).span_label(lifetime_j.span, "declared twice")
+                     .span_label(lifetime_i.span, "previous declaration here")
+                     .emit();
                 }
             }
 
             // It is a soft error to shadow a lifetime within a parent scope.
-            self.check_lifetime_def_for_shadowing(old_scope, &lifetime_i.lifetime);
+            self.check_lifetime_param_for_shadowing(old_scope, &lifetime_i);
 
             for bound in &lifetime_i.bounds {
-                match bound.name {
-                    hir::LifetimeName::Underscore => {
-                        let mut err = struct_span_err!(
-                            self.tcx.sess,
-                            bound.span,
-                            E0637,
-                            "invalid lifetime bound name: `'_`"
-                        );
-                        err.span_label(bound.span, "`'_` is a reserved lifetime name");
-                        err.emit();
-                    }
-                    hir::LifetimeName::Static => {
-                        self.insert_lifetime(bound, Region::Static);
-                        self.tcx
-                            .sess
-                            .struct_span_warn(
-                                lifetime_i.lifetime.span.to(bound.span),
+                match bound {
+                    hir::GenericBound::Outlives(lt) => match lt.name {
+                        hir::LifetimeName::Underscore => {
+                            let mut err = struct_span_err!(
+                                self.tcx.sess,
+                                lt.span,
+                                E0637,
+                                "invalid lifetime bound name: `'_`"
+                            );
+                            err.span_label(lt.span, "`'_` is a reserved lifetime name");
+                            err.emit();
+                        }
+                        hir::LifetimeName::Static => {
+                            self.insert_lifetime(lt, Region::Static);
+                            self.tcx.sess.struct_span_warn(
+                                lifetime_i.span.to(lt.span),
                                 &format!(
                                     "unnecessary lifetime parameter `{}`",
-                                    lifetime_i.lifetime.name.name()
+                                    lifetime_i.name.name(),
                                 ),
-                            )
-                            .help(&format!(
+                            ).help(&format!(
                                 "you can use the `'static` lifetime directly, in place \
-                                 of `{}`",
-                                lifetime_i.lifetime.name.name()
-                            ))
-                            .emit();
-                    }
-                    hir::LifetimeName::Fresh(_)
-                    | hir::LifetimeName::Implicit
-                    | hir::LifetimeName::Name(_) => {
-                        self.resolve_lifetime_ref(bound);
+                                    of `{}`",
+                                lifetime_i.name.name(),
+                            )).emit();
+                        }
+                        hir::LifetimeName::Param(_)
+                        | hir::LifetimeName::Implicit => {
+                            self.resolve_lifetime_ref(lt);
+                        }
                     }
+                    _ => bug!(),
                 }
             }
         }
     }
 
-    fn check_lifetime_def_for_shadowing(
+    fn check_lifetime_param_for_shadowing(
         &self,
         mut old_scope: ScopeRef,
-        lifetime: &'tcx hir::Lifetime,
+        param: &'tcx hir::GenericParam,
     ) {
         for &(label, label_span) in &self.labels_in_fn {
             // FIXME (#24278): non-hygienic comparison
-            if lifetime.name.name() == label {
+            if param.name.name() == label {
                 signal_shadowing_problem(
                     self.tcx,
                     label,
                     original_label(label_span),
-                    shadower_lifetime(&lifetime),
+                    shadower_lifetime(&param),
                 );
                 return;
             }
@@ -2273,14 +2353,14 @@ fn check_lifetime_def_for_shadowing(
                 Scope::Binder {
                     ref lifetimes, s, ..
                 } => {
-                    if let Some(&def) = lifetimes.get(&lifetime.name) {
+                    if let Some(&def) = lifetimes.get(&param.name) {
                         let node_id = self.tcx.hir.as_local_node_id(def.id().unwrap()).unwrap();
 
                         signal_shadowing_problem(
                             self.tcx,
-                            lifetime.name.name(),
+                            param.name.name(),
                             original_lifetime(self.tcx.hir.span(node_id)),
-                            shadower_lifetime(&lifetime),
+                            shadower_lifetime(&param),
                         );
                         return;
                     }
@@ -2377,6 +2457,14 @@ fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) {
             }
         }
     }
+
+    /// Sometimes we resolve a lifetime, but later find that it is an
+    /// error (esp. around impl trait). In that case, we remove the
+    /// entry into `map.defs` so as not to confuse later code.
+    fn uninsert_lifetime_on_error(&mut self, lifetime_ref: &'tcx hir::Lifetime, bad_def: Region) {
+        let old_value = self.map.defs.remove(&lifetime_ref.id);
+        assert_eq!(old_value, Some(bad_def));
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -2428,14 +2516,14 @@ fn insert_late_bound_lifetimes(
     appears_in_where_clause.visit_generics(generics);
 
     for param in &generics.params {
-        match *param {
-            hir::GenericParam::Lifetime(ref lifetime_def) => {
-                if !lifetime_def.bounds.is_empty() {
+        match param.kind {
+            hir::GenericParamKind::Lifetime { .. } => {
+                if !param.bounds.is_empty() {
                     // `'a: 'b` means both `'a` and `'b` are referenced
-                    appears_in_where_clause.regions.insert(lifetime_def.lifetime.name);
+                    appears_in_where_clause.regions.insert(hir::LifetimeName::Param(param.name));
                 }
             }
-            hir::GenericParam::Type(_) => {}
+            hir::GenericParamKind::Type { .. } => {}
         }
     }
 
@@ -2448,33 +2536,26 @@ fn insert_late_bound_lifetimes(
     // - appear in the inputs
     // - do not appear in the where-clauses
     // - are not implicitly captured by `impl Trait`
-    for lifetime in generics.lifetimes() {
-        let name = lifetime.lifetime.name;
-
+    for param in &generics.params {
+        let lt_name = hir::LifetimeName::Param(param.name);
         // appears in the where clauses? early-bound.
-        if appears_in_where_clause.regions.contains(&name) {
+        if appears_in_where_clause.regions.contains(&lt_name) {
             continue;
         }
 
         // does not appear in the inputs, but appears in the return type? early-bound.
-        if !constrained_by_input.regions.contains(&name)
-            && appears_in_output.regions.contains(&name)
+        if !constrained_by_input.regions.contains(&lt_name)
+            && appears_in_output.regions.contains(&lt_name)
         {
             continue;
         }
 
-        debug!(
-            "insert_late_bound_lifetimes: \
-             lifetime {:?} with id {:?} is late-bound",
-            lifetime.lifetime.name, lifetime.lifetime.id
-        );
+        debug!("insert_late_bound_lifetimes: lifetime {:?} with id {:?} is late-bound",
+               param.name.name(),
+               param.id);
 
-        let inserted = map.late_bound.insert(lifetime.lifetime.id);
-        assert!(
-            inserted,
-            "visited lifetime {:?} twice",
-            lifetime.lifetime.id
-        );
+        let inserted = map.late_bound.insert(param.id);
+        assert!(inserted, "visited lifetime {:?} twice", param.id);
     }
 
     return;
index d6a7d5e8472ac086dab3b6dec23b6cc37664f8cd..4cdc9fdddbf80b1176de05bdd44b9a26ab91315a 100644 (file)
@@ -614,10 +614,12 @@ pub fn eval_stability(self, def_id: DefId, id: Option<NodeId>, span: Span) -> Ev
         debug!("stability: \
                 inspecting def_id={:?} span={:?} of stability={:?}", def_id, span, stability);
 
-        if let Some(&Stability{rustc_depr: Some(attr::RustcDeprecation { reason, .. }), ..})
+        if let Some(&Stability{rustc_depr: Some(attr::RustcDeprecation { reason, since }), ..})
                 = stability {
             if let Some(id) = id {
-                lint_deprecated(def_id, id, Some(reason));
+                if deprecation_in_effect(&since.as_str()) {
+                    lint_deprecated(def_id, id, Some(reason));
+                }
             }
         }
 
index 87fb0a6b70ace31e42352020b9097e26520dc754..ee6cb398acdceecef12b853bc67886eeeb0a61ee 100644 (file)
@@ -10,7 +10,7 @@
 
 //! MIR datatypes and passes. See the [rustc guide] for more info.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir.html
+//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/index.html
 
 use graphviz::IntoCow;
 use hir::def::CtorKind;
index 227cba40d146388a016431509201bd3a522f3c94..f48739799203fb9c41453c7a2f7592f42daf72a6 100644 (file)
@@ -224,11 +224,9 @@ pub fn find_auto_trait_generics<A>(
             let names_map: FxHashSet<String> = generics
                 .params
                 .iter()
-                .filter_map(|param| {
-                    match param.kind {
-                        ty::GenericParamDefKind::Lifetime => Some(param.name.to_string()),
-                        _ => None
-                    }
+                .filter_map(|param| match param.kind {
+                    ty::GenericParamDefKind::Lifetime => Some(param.name.to_string()),
+                    _ => None
                 })
                 .collect();
 
index 5a626e7b82cc47c17f5b297dc63a9dc6ec1ad0a3..6a6bebdbd8652ca4fdc420419ffd6880af6d3215 100644 (file)
@@ -11,8 +11,8 @@
 //! See rustc guide chapters on [trait-resolution] and [trait-specialization] for more info on how
 //! this works.
 //!
-//! [trait-resolution]: https://rust-lang-nursery.github.io/rustc-guide/trait-resolution.html
-//! [trait-specialization]: https://rust-lang-nursery.github.io/rustc-guide/trait-specialization.html
+//! [trait-resolution]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html
+//! [trait-specialization]: https://rust-lang-nursery.github.io/rustc-guide/traits/specialization.html
 
 use hir::def_id::{DefId, LOCAL_CRATE};
 use syntax_pos::DUMMY_SP;
index f76b312ee530daebf773f2c4c9acf66b5175b026..0d7d39ccf40dfcff2e069e7537c8d5472f5becba 100644 (file)
@@ -366,9 +366,8 @@ fn on_unimplemented_note(
         }
 
         if let Some(k) = obligation.cause.span.compiler_desugaring_kind() {
-            let desugaring = k.as_symbol().as_str();
             flags.push(("from_desugaring".to_string(), None));
-            flags.push(("from_desugaring".to_string(), Some(desugaring.to_string())));
+            flags.push(("from_desugaring".to_string(), Some(k.name().to_string())));
         }
         let generics = self.tcx.generics_of(def_id);
         let self_ty = trait_ref.self_ty();
index 761de0014384265933c40d77a94430659c83d95b..15f0b8eebc1db92b0d9a6a8271369f4cf20f0cd6 100644 (file)
@@ -10,7 +10,7 @@
 
 //! Trait Resolution. See [rustc guide] for more info on how this works.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-resolution.html
+//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html
 
 pub use self::SelectionError::*;
 pub use self::FulfillmentErrorCode::*;
@@ -269,7 +269,9 @@ pub struct DerivedObligationCause<'tcx> {
 pub type TraitObligations<'tcx> = Vec<TraitObligation<'tcx>>;
 
 /// The following types:
-/// * `WhereClauseAtom`
+/// * `WhereClause`
+/// * `WellFormed`
+/// * `FromEnv`
 /// * `DomainGoal`
 /// * `Goal`
 /// * `Clause`
@@ -277,21 +279,31 @@ pub struct DerivedObligationCause<'tcx> {
 /// logic programming clauses. They are part of the interface
 /// for the chalk SLG solver.
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
-pub enum WhereClauseAtom<'tcx> {
+pub enum WhereClause<'tcx> {
     Implemented(ty::TraitPredicate<'tcx>),
     ProjectionEq(ty::ProjectionPredicate<'tcx>),
+    RegionOutlives(ty::RegionOutlivesPredicate<'tcx>),
+    TypeOutlives(ty::TypeOutlivesPredicate<'tcx>),
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
+pub enum WellFormed<'tcx> {
+    Trait(ty::TraitPredicate<'tcx>),
+    Ty(Ty<'tcx>),
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
+pub enum FromEnv<'tcx> {
+    Trait(ty::TraitPredicate<'tcx>),
+    Ty(Ty<'tcx>),
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
 pub enum DomainGoal<'tcx> {
-    Holds(WhereClauseAtom<'tcx>),
-    WellFormed(WhereClauseAtom<'tcx>),
-    FromEnv(WhereClauseAtom<'tcx>),
-    WellFormedTy(Ty<'tcx>),
+    Holds(WhereClause<'tcx>),
+    WellFormed(WellFormed<'tcx>),
+    FromEnv(FromEnv<'tcx>),
     Normalize(ty::ProjectionPredicate<'tcx>),
-    FromEnvTy(Ty<'tcx>),
-    RegionOutlives(ty::RegionOutlivesPredicate<'tcx>),
-    TypeOutlives(ty::TypeOutlivesPredicate<'tcx>),
 }
 
 pub type PolyDomainGoal<'tcx> = ty::Binder<DomainGoal<'tcx>>;
@@ -314,27 +326,27 @@ pub enum Goal<'tcx> {
 
 pub type Goals<'tcx> = &'tcx Slice<Goal<'tcx>>;
 
+impl<'tcx> DomainGoal<'tcx> {
+    pub fn into_goal(self) -> Goal<'tcx> {
+        Goal::DomainGoal(self)
+    }
+}
+
 impl<'tcx> Goal<'tcx> {
     pub fn from_poly_domain_goal<'a>(
         domain_goal: PolyDomainGoal<'tcx>,
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
     ) -> Goal<'tcx> {
         match domain_goal.no_late_bound_regions() {
-            Some(p) => p.into(),
+            Some(p) => p.into_goal(),
             None => Goal::Quantified(
                 QuantifierKind::Universal,
-                domain_goal.map_bound(|p| tcx.mk_goal(Goal::from(p)))
+                domain_goal.map_bound(|p| tcx.mk_goal(p.into_goal()))
             ),
         }
     }
 }
 
-impl<'tcx> From<DomainGoal<'tcx>> for Goal<'tcx> {
-    fn from(domain_goal: DomainGoal<'tcx>) -> Self {
-        Goal::DomainGoal(domain_goal)
-    }
-}
-
 /// This matches the definition from Page 7 of "A Proof Procedure for the Logic of Hereditary
 /// Harrop Formulas".
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
index 6c67c10dc69cf490dd3120bb064e5cc90ea5def4..85bd5853d18a74c8b6420ccbc1c0194d635fa9c1 100644 (file)
 use super::elaborate_predicates;
 
 use hir::def_id::DefId;
+use lint;
 use traits;
 use ty::{self, Ty, TyCtxt, TypeFoldable};
 use ty::subst::Substs;
 use ty::util::ExplicitSelf;
 use std::borrow::Cow;
 use syntax::ast;
+use syntax_pos::Span;
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 pub enum ObjectSafetyViolation {
     /// Self : Sized declared on the trait
     SizedSelf,
@@ -56,6 +58,9 @@ pub fn error_msg(&self) -> Cow<'static, str> {
             ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf) =>
                 format!("method `{}` references the `Self` type \
                          in its arguments or return type", name).into(),
+            ObjectSafetyViolation::Method(name,
+                                            MethodViolationCode::WhereClauseReferencesSelf(_)) =>
+                format!("method `{}` references the `Self` type in where clauses", name).into(),
             ObjectSafetyViolation::Method(name, MethodViolationCode::Generic) =>
                 format!("method `{}` has generic type parameters", name).into(),
             ObjectSafetyViolation::Method(name, MethodViolationCode::NonStandardSelfType) =>
@@ -75,6 +80,9 @@ pub enum MethodViolationCode {
     /// e.g., `fn foo(&self, x: Self)` or `fn foo(&self) -> Self`
     ReferencesSelf,
 
+    /// e.g. `fn foo(&self) where Self: Clone`
+    WhereClauseReferencesSelf(Span),
+
     /// e.g., `fn foo<A>()`
     Generic,
 
@@ -123,6 +131,22 @@ fn object_safety_violations_for_trait(self, trait_def_id: DefId)
             .filter_map(|item| {
                 self.object_safety_violation_for_method(trait_def_id, &item)
                     .map(|code| ObjectSafetyViolation::Method(item.name, code))
+            }).filter(|violation| {
+                if let ObjectSafetyViolation::Method(_,
+                                MethodViolationCode::WhereClauseReferencesSelf(span)) = violation {
+                    // Using`CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
+                    // It's also hard to get a use site span, so we use the method definition span.
+                    self.lint_node_note(
+                        lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY,
+                        ast::CRATE_NODE_ID,
+                        *span,
+                        &format!("the trait `{}` cannot be made into an object",
+                                self.item_path_str(trait_def_id)),
+                        &violation.error_msg());
+                    false
+                } else {
+                    true
+                }
             }).collect();
 
         // Check the trait itself.
@@ -245,7 +269,10 @@ pub fn is_vtable_safe_method(self,
             return false;
         }
 
-        self.virtual_call_violation_for_method(trait_def_id, method).is_none()
+        match self.virtual_call_violation_for_method(trait_def_id, method) {
+            None | Some(MethodViolationCode::WhereClauseReferencesSelf(_)) => true,
+            Some(_) => false,
+        }
     }
 
     /// Returns `Some(_)` if this method cannot be called on a trait
@@ -288,6 +315,18 @@ fn virtual_call_violation_for_method(self,
             return Some(MethodViolationCode::Generic);
         }
 
+        if self.predicates_of(method.def_id).predicates.into_iter()
+                // A trait object can't claim to live more than the concrete type,
+                // so outlives predicates will always hold.
+                .filter(|p| p.to_opt_type_outlives().is_none())
+                .collect::<Vec<_>>()
+                // Do a shallow visit so that `contains_illegal_self_type_reference`
+                // may apply it's custom visiting.
+                .visit_tys_shallow(|t| self.contains_illegal_self_type_reference(trait_def_id, t)) {
+            let span = self.def_span(method.def_id);
+            return Some(MethodViolationCode::WhereClauseReferencesSelf(span));
+        }
+
         None
     }
 
index 08af80543dff2c51a936c2584fc023708f5f6be5..fe30b6a2f88b7be9e4ccc8bb73a2b819bd1c00a8 100644 (file)
@@ -10,7 +10,7 @@
 
 //! See [rustc guide] for more info on how this works.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-resolution.html#selection
+//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#selection
 
 use self::SelectionCandidate::*;
 use self::EvaluationResult::*;
@@ -1047,7 +1047,7 @@ fn insert_evaluation_cache(&mut self,
     // candidates. See [rustc guide] for more details.
     //
     // [rustc guide]:
-    // https://rust-lang-nursery.github.io/rustc-guide/trait-resolution.html#candidate-assembly
+    // https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#candidate-assembly
 
     fn candidate_from_obligation<'o>(&mut self,
                                      stack: &TraitObligationStack<'o, 'tcx>)
@@ -2415,7 +2415,7 @@ fn collect_predicates_for_types(&mut self,
     // type error.  See [rustc guide] for more details.
     //
     // [rustc guide]:
-    // https://rust-lang-nursery.github.io/rustc-guide/trait-resolution.html#confirmation
+    // https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#confirmation
 
     fn confirm_candidate(&mut self,
                          obligation: &TraitObligation<'tcx>,
index d33806285142e4ba90de19eeac6cf240684892f0..f6ae5113cb2a5505e3ed72b0e659f9bacfd02605 100644 (file)
@@ -17,7 +17,7 @@
 //! See the [rustc guide] for a bit more detail on how specialization
 //! fits together with the rest of the trait machinery.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-specialization.html
+//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/specialization.html
 
 use super::{SelectionContext, FulfillmentContext};
 use super::util::impl_trait_ref_and_oblig;
index d1304a0a3f8871483a6f6c1546a9acd945010a5e..d24c84b2556f860653902fb8aace1aa896b6940c 100644 (file)
@@ -405,13 +405,37 @@ impl<'tcx, T> TypeFoldable<'tcx> for Normalized<'tcx, T> {
     } where T: TypeFoldable<'tcx>
 }
 
-impl<'tcx> fmt::Display for traits::WhereClauseAtom<'tcx> {
+impl<'tcx> fmt::Display for traits::WhereClause<'tcx> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        use traits::WhereClauseAtom::*;
+        use traits::WhereClause::*;
 
         match self {
             Implemented(trait_ref) => write!(fmt, "Implemented({})", trait_ref),
             ProjectionEq(projection) => write!(fmt, "ProjectionEq({})", projection),
+            RegionOutlives(predicate) => write!(fmt, "RegionOutlives({})", predicate),
+            TypeOutlives(predicate) => write!(fmt, "TypeOutlives({})", predicate),
+        }
+    }
+}
+
+impl<'tcx> fmt::Display for traits::WellFormed<'tcx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        use traits::WellFormed::*;
+
+        match self {
+            Trait(trait_ref) => write!(fmt, "WellFormed({})", trait_ref),
+            Ty(ty) => write!(fmt, "WellFormed({})", ty),
+        }
+    }
+}
+
+impl<'tcx> fmt::Display for traits::FromEnv<'tcx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        use traits::FromEnv::*;
+
+        match self {
+            Trait(trait_ref) => write!(fmt, "FromEnv({})", trait_ref),
+            Ty(ty) => write!(fmt, "FromEnv({})", ty),
         }
     }
 }
@@ -419,19 +443,12 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 impl<'tcx> fmt::Display for traits::DomainGoal<'tcx> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         use traits::DomainGoal::*;
-        use traits::WhereClauseAtom::*;
 
         match self {
             Holds(wc) => write!(fmt, "{}", wc),
-            WellFormed(Implemented(trait_ref)) => write!(fmt, "WellFormed({})", trait_ref),
-            WellFormed(ProjectionEq(projection)) => write!(fmt, "WellFormed({})", projection),
-            FromEnv(Implemented(trait_ref)) => write!(fmt, "FromEnv({})", trait_ref),
-            FromEnv(ProjectionEq(projection)) => write!(fmt, "FromEnv({})", projection),
-            WellFormedTy(ty) => write!(fmt, "WellFormed({})", ty),
+            WellFormed(wf) => write!(fmt, "{}", wf),
+            FromEnv(from_env) => write!(fmt, "{}", from_env),
             Normalize(projection) => write!(fmt, "Normalize({})", projection),
-            FromEnvTy(ty) => write!(fmt, "FromEnv({})", ty),
-            RegionOutlives(predicate) => write!(fmt, "RegionOutlives({})", predicate),
-            TypeOutlives(predicate) => write!(fmt, "TypeOutlives({})", predicate),
         }
     }
 }
@@ -506,30 +523,60 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 }
 
 EnumTypeFoldableImpl! {
-    impl<'tcx> TypeFoldable<'tcx> for traits::WhereClauseAtom<'tcx> {
-        (traits::WhereClauseAtom::Implemented)(trait_ref),
-        (traits::WhereClauseAtom::ProjectionEq)(projection),
+    impl<'tcx> TypeFoldable<'tcx> for traits::WhereClause<'tcx> {
+        (traits::WhereClause::Implemented)(trait_ref),
+        (traits::WhereClause::ProjectionEq)(projection),
+        (traits::WhereClause::TypeOutlives)(ty_outlives),
+        (traits::WhereClause::RegionOutlives)(region_outlives),
+    }
+}
+
+EnumLiftImpl! {
+    impl<'a, 'tcx> Lift<'tcx> for traits::WhereClause<'a> {
+        type Lifted = traits::WhereClause<'tcx>;
+        (traits::WhereClause::Implemented)(trait_ref),
+        (traits::WhereClause::ProjectionEq)(projection),
+        (traits::WhereClause::TypeOutlives)(ty_outlives),
+        (traits::WhereClause::RegionOutlives)(region_outlives),
+    }
+}
+
+EnumTypeFoldableImpl! {
+    impl<'tcx> TypeFoldable<'tcx> for traits::WellFormed<'tcx> {
+        (traits::WellFormed::Trait)(trait_ref),
+        (traits::WellFormed::Ty)(ty),
+    }
+}
+
+EnumLiftImpl! {
+    impl<'a, 'tcx> Lift<'tcx> for traits::WellFormed<'a> {
+        type Lifted = traits::WellFormed<'tcx>;
+        (traits::WellFormed::Trait)(trait_ref),
+        (traits::WellFormed::Ty)(ty),
+    }
+}
+
+EnumTypeFoldableImpl! {
+    impl<'tcx> TypeFoldable<'tcx> for traits::FromEnv<'tcx> {
+        (traits::FromEnv::Trait)(trait_ref),
+        (traits::FromEnv::Ty)(ty),
     }
 }
 
 EnumLiftImpl! {
-    impl<'a, 'tcx> Lift<'tcx> for traits::WhereClauseAtom<'a> {
-        type Lifted = traits::WhereClauseAtom<'tcx>;
-        (traits::WhereClauseAtom::Implemented)(trait_ref),
-        (traits::WhereClauseAtom::ProjectionEq)(projection),
+    impl<'a, 'tcx> Lift<'tcx> for traits::FromEnv<'a> {
+        type Lifted = traits::FromEnv<'tcx>;
+        (traits::FromEnv::Trait)(trait_ref),
+        (traits::FromEnv::Ty)(ty),
     }
 }
 
 EnumTypeFoldableImpl! {
     impl<'tcx> TypeFoldable<'tcx> for traits::DomainGoal<'tcx> {
         (traits::DomainGoal::Holds)(wc),
-        (traits::DomainGoal::WellFormed)(wc),
-        (traits::DomainGoal::FromEnv)(wc),
-        (traits::DomainGoal::WellFormedTy)(ty),
+        (traits::DomainGoal::WellFormed)(wf),
+        (traits::DomainGoal::FromEnv)(from_env),
         (traits::DomainGoal::Normalize)(projection),
-        (traits::DomainGoal::FromEnvTy)(ty),
-        (traits::DomainGoal::RegionOutlives)(predicate),
-        (traits::DomainGoal::TypeOutlives)(predicate),
     }
 }
 
@@ -537,13 +584,9 @@ impl<'tcx> TypeFoldable<'tcx> for traits::DomainGoal<'tcx> {
     impl<'a, 'tcx> Lift<'tcx> for traits::DomainGoal<'a> {
         type Lifted = traits::DomainGoal<'tcx>;
         (traits::DomainGoal::Holds)(wc),
-        (traits::DomainGoal::WellFormed)(wc),
-        (traits::DomainGoal::FromEnv)(wc),
-        (traits::DomainGoal::WellFormedTy)(ty),
+        (traits::DomainGoal::WellFormed)(wf),
+        (traits::DomainGoal::FromEnv)(from_env),
         (traits::DomainGoal::Normalize)(projection),
-        (traits::DomainGoal::FromEnvTy)(ty),
-        (traits::DomainGoal::RegionOutlives)(predicate),
-        (traits::DomainGoal::TypeOutlives)(predicate),
     }
 }
 
index d459a6de0d69e3293b5fbff0562662201c47d1ca..307e1b238386c0e912675295010249613e24e73a 100644 (file)
@@ -136,6 +136,20 @@ fn is_global(&self) -> bool {
     fn has_late_bound_regions(&self) -> bool {
         self.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND)
     }
+
+    /// A visitor that does not recurse into types, works like `fn walk_shallow` in `Ty`.
+    fn visit_tys_shallow(&self, visit: impl FnMut(Ty<'tcx>) -> bool) -> bool {
+
+        pub struct Visitor<F>(F);
+
+        impl<'tcx, F: FnMut(Ty<'tcx>) -> bool> TypeVisitor<'tcx> for Visitor<F> {
+            fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
+                self.0(ty)
+            }
+        }
+
+        self.visit_with(&mut Visitor(visit))
+    }
 }
 
 /// The TypeFolder trait defines the actual *folding*. There is a
index d858ba7acf7863bf1da169566d194b99404db518..479fbe2673b97357a8d54aaa37dd41e06c6d0433 100644 (file)
@@ -215,7 +215,7 @@ pub fn push_item_path<T>(self, buffer: &mut T, def_id: DefId)
             data @ DefPathData::ValueNs(..) |
             data @ DefPathData::Module(..) |
             data @ DefPathData::TypeParam(..) |
-            data @ DefPathData::LifetimeDef(..) |
+            data @ DefPathData::LifetimeParam(..) |
             data @ DefPathData::EnumVariant(..) |
             data @ DefPathData::Field(..) |
             data @ DefPathData::AnonConst |
index 4f5f0c9d740cc8c0429b43d1861af779f5a1ec5d..ce7098314557939fc59623815997c138ba2b01e7 100644 (file)
@@ -2732,13 +2732,14 @@ pub fn hygienic_eq(self, use_name: Name, def_name: Name, def_parent_def_id: DefI
     }
 
     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),
+        ident = ident.modern();
+        let target_expansion = match scope.krate {
+            LOCAL_CRATE => self.hir.definitions().opaque_expansion_that_defined(scope.index),
             _ => Mark::root(),
         };
-        ident = ident.modern();
-        let scope = match ident.span.adjust(expansion) {
-            Some(macro_def) => self.hir.definitions().macro_def_scope(macro_def),
+        let scope = match ident.span.adjust(target_expansion) {
+            Some(actual_expansion) =>
+                self.hir.definitions().parent_module_of_macro_def(actual_expansion),
             None if block == DUMMY_NODE_ID => DefId::local(CRATE_DEF_INDEX), // Dummy DefId
             None => self.hir.get_module_parent(block),
         };
index 4a69fbdacc476a006051365189d339bcedc0b329..d8ca817ff2bd0314021f627f4f6869d4862f8d39 100644 (file)
@@ -1087,7 +1087,7 @@ pub fn is_self(&self) -> bool {
 ///
 /// [1]: http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
 /// [2]: http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
-/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html
+/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/hrtb.html
 #[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
 pub enum RegionKind {
     // Region bound in a type or fn declaration which will be
index 883882dfe6837f22be689cc3c2aa5499fd7ee386..4fe9c34c140cbdf8136258728b33931570fdffa0 100644 (file)
@@ -287,7 +287,7 @@ fn parameterized<F: fmt::Write>(&mut self,
                     DefPathData::MacroDef(_) |
                     DefPathData::ClosureExpr |
                     DefPathData::TypeParam(_) |
-                    DefPathData::LifetimeDef(_) |
+                    DefPathData::LifetimeParam(_) |
                     DefPathData::Field(_) |
                     DefPathData::StructCtor |
                     DefPathData::AnonConst |
@@ -336,12 +336,10 @@ fn parameterized<F: fmt::Write>(&mut self,
 
             if !verbose {
                 let mut type_params =
-                    generics.params.iter().rev().filter_map(|param| {
-                        match param.kind {
-                            GenericParamDefKind::Type { has_default, .. } => {
-                                Some((param.def_id, has_default))
-                            }
-                            GenericParamDefKind::Lifetime => None,
+                    generics.params.iter().rev().filter_map(|param| match param.kind {
+                        GenericParamDefKind::Lifetime => None,
+                        GenericParamDefKind::Type { has_default, .. } => {
+                            Some((param.def_id, has_default))
                         }
                     }).peekable();
                 let has_default = {
@@ -1064,10 +1062,14 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 TyParam(ref param_ty) => write!(f, "{}", param_ty),
                 TyAdt(def, substs) => cx.parameterized(f, substs, def.did, &[]),
                 TyDynamic(data, r) => {
-                    data.print(f, cx)?;
                     let r = r.print_to_string(cx);
                     if !r.is_empty() {
-                        write!(f, " + {}", r)
+                        write!(f, "(")?;
+                    }
+                    write!(f, "dyn ")?;
+                    data.print(f, cx)?;
+                    if !r.is_empty() {
+                        write!(f, " + {})", r)
                     } else {
                         Ok(())
                     }
index 765cb80f35710b30e742711ff434cdca4c9c1de4..1cbde181cafae7e80ebab6815e6fbb2a3284b822 100644 (file)
@@ -14,3 +14,4 @@ rustc_errors = { path = "../librustc_errors" }
 rustc_target = { path = "../librustc_target" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
+log = "0.4"
index ec0676259ef20845f4ae2f1f62f797cc5588268d..60d28d8098b4ca656b7b86cbb6617c63adf3dba7 100644 (file)
 
 use rustc::middle::allocator::AllocatorKind;
 use rustc_errors;
-use rustc_target::spec::abi::Abi;
-use syntax::ast::{Attribute, Crate, LitKind, StrStyle};
-use syntax::ast::{Arg, Constness, Generics, Mac, Mutability, Ty, Unsafety};
-use syntax::ast::{self, Expr, Ident, Item, ItemKind, TyKind, VisibilityKind};
-use syntax::attr;
-use syntax::codemap::{dummy_spanned, respan};
-use syntax::codemap::{ExpnInfo, MacroAttribute, NameAndSpan};
-use syntax::ext::base::ExtCtxt;
-use syntax::ext::base::Resolver;
-use syntax::ext::build::AstBuilder;
-use syntax::ext::expand::ExpansionConfig;
-use syntax::ext::hygiene::{self, Mark, SyntaxContext};
-use syntax::fold::{self, Folder};
-use syntax::parse::ParseSess;
-use syntax::ptr::P;
-use syntax::symbol::Symbol;
-use syntax::util::small_vector::SmallVector;
-use syntax_pos::{Span, DUMMY_SP};
+use syntax::{
+    ast::{
+        self, Arg, Attribute, Crate, Expr, FnHeader, Generics, Ident, Item, ItemKind,
+        LitKind, Mac, Mod, Mutability, StrStyle, Ty, TyKind, Unsafety, VisibilityKind,
+    },
+    attr,
+    codemap::{
+        respan, ExpnInfo, MacroAttribute,
+    },
+    ext::{
+        base::{ExtCtxt, Resolver},
+        build::AstBuilder,
+        expand::ExpansionConfig,
+        hygiene::{self, Mark, SyntaxContext},
+    },
+    fold::{self, Folder},
+    parse::ParseSess,
+    ptr::P,
+    symbol::Symbol,
+    util::small_vector::SmallVector,
+};
+use syntax_pos::Span;
 
 use {AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS};
 
@@ -35,6 +39,7 @@ pub fn modify(
     sess: &ParseSess,
     resolver: &mut Resolver,
     krate: Crate,
+    crate_name: String,
     handler: &rustc_errors::Handler,
 ) -> ast::Crate {
     ExpandAllocatorDirectives {
@@ -42,6 +47,8 @@ pub fn modify(
         sess,
         resolver,
         found: false,
+        crate_name: Some(crate_name),
+        in_submod: -1, // -1 to account for the "root" module
     }.fold_crate(krate)
 }
 
@@ -50,10 +57,17 @@ struct ExpandAllocatorDirectives<'a> {
     handler: &'a rustc_errors::Handler,
     sess: &'a ParseSess,
     resolver: &'a mut Resolver,
+    crate_name: Option<String>,
+
+    // For now, we disallow `global_allocator` in submodules because hygiene is hard. Keep track of
+    // whether we are in a submodule or not. If `in_submod > 0` we are in a submodule.
+    in_submod: isize,
 }
 
 impl<'a> Folder for ExpandAllocatorDirectives<'a> {
     fn fold_item(&mut self, item: P<Item>) -> SmallVector<P<Item>> {
+        debug!("in submodule {}", self.in_submod);
+
         let name = if attr::contains_name(&item.attrs, "global_allocator") {
             "global_allocator"
         } else {
@@ -68,29 +82,37 @@ fn fold_item(&mut self, item: P<Item>) -> SmallVector<P<Item>> {
             }
         }
 
+        if self.in_submod > 0 {
+            self.handler
+                .span_err(item.span, "`global_allocator` cannot be used in submodules");
+            return SmallVector::one(item);
+        }
+
         if self.found {
-            self.handler.span_err(
-                item.span,
-                "cannot define more than one \
-                 #[global_allocator]",
-            );
+            self.handler
+                .span_err(item.span, "cannot define more than one #[global_allocator]");
             return SmallVector::one(item);
         }
         self.found = true;
 
+        // Create a fresh Mark for the new macro expansion we are about to do
         let mark = Mark::fresh(Mark::root());
         mark.set_expn_info(ExpnInfo {
-            call_site: DUMMY_SP,
-            callee: NameAndSpan {
-                format: MacroAttribute(Symbol::intern(name)),
-                span: None,
-                allow_internal_unstable: true,
-                allow_internal_unsafe: false,
-                edition: hygiene::default_edition(),
-            },
+            call_site: item.span, // use the call site of the static
+            def_site: None,
+            format: MacroAttribute(Symbol::intern(name)),
+            allow_internal_unstable: true,
+            allow_internal_unsafe: false,
+            edition: hygiene::default_edition(),
         });
+
+        // Tie the span to the macro expansion info we just created
         let span = item.span.with_ctxt(SyntaxContext::empty().apply_mark(mark));
-        let ecfg = ExpansionConfig::default(name.to_string());
+
+        // Create an expansion config
+        let ecfg = ExpansionConfig::default(self.crate_name.take().unwrap());
+
+        // Generate a bunch of new items using the AllocFnFactory
         let mut f = AllocFnFactory {
             span,
             kind: AllocatorKind::Global,
@@ -98,29 +120,55 @@ fn fold_item(&mut self, item: P<Item>) -> SmallVector<P<Item>> {
             core: Ident::from_str("core"),
             cx: ExtCtxt::new(self.sess, ecfg, self.resolver),
         };
+
+        // We will generate a new submodule. To `use` the static from that module, we need to get
+        // the `super::...` path.
         let super_path = f.cx.path(f.span, vec![Ident::from_str("super"), f.global]);
+
+        // Generate the items in the submodule
         let mut items = vec![
+            // import `core` to use allocators
             f.cx.item_extern_crate(f.span, f.core),
+            // `use` the `global_allocator` in `super`
             f.cx.item_use_simple(
                 f.span,
                 respan(f.span.shrink_to_lo(), VisibilityKind::Inherited),
                 super_path,
             ),
         ];
-        for method in ALLOCATOR_METHODS {
-            items.push(f.allocator_fn(method));
-        }
+
+        // Add the allocator methods to the submodule
+        items.extend(
+            ALLOCATOR_METHODS
+                .iter()
+                .map(|method| f.allocator_fn(method)),
+        );
+
+        // Generate the submodule itself
         let name = f.kind.fn_name("allocator_abi");
         let allocator_abi = Ident::with_empty_ctxt(Symbol::gensym(&name));
         let module = f.cx.item_mod(span, span, allocator_abi, Vec::new(), items);
         let module = f.cx.monotonic_expander().fold_item(module).pop().unwrap();
 
-        let mut ret = SmallVector::new();
+        // Return the item and new submodule
+        let mut ret = SmallVector::with_capacity(2);
         ret.push(item);
         ret.push(module);
+
         return ret;
     }
 
+    // If we enter a submodule, take note.
+    fn fold_mod(&mut self, m: Mod) -> Mod {
+        debug!("enter submodule");
+        self.in_submod += 1;
+        let ret = fold::noop_fold_mod(m, self);
+        self.in_submod -= 1;
+        debug!("exit submodule");
+        ret
+    }
+
+    // `fold_mac` is disabled by default. Enable it here.
     fn fold_mac(&mut self, mac: Mac) -> Mac {
         fold::noop_fold_mac(mac, self)
     }
@@ -152,9 +200,10 @@ fn allocator_fn(&self, method: &AllocatorMethod) -> P<Item> {
         let (output_ty, output_expr) = self.ret_ty(&method.output, result);
         let kind = ItemKind::Fn(
             self.cx.fn_decl(abi_args, ast::FunctionRetTy::Ty(output_ty)),
-            Unsafety::Unsafe,
-            dummy_spanned(Constness::NotConst),
-            Abi::Rust,
+            FnHeader {
+                unsafety: Unsafety::Unsafe,
+                ..FnHeader::default()
+            },
             Generics::default(),
             self.cx.block_expr(output_expr),
         );
index 6595564fb30b5ccc0f1ab750ce258bb631721452..b217d3665a24542306a6dceb838acbf80f7ab428 100644 (file)
@@ -10,6 +10,7 @@
 
 #![feature(rustc_private)]
 
+#[macro_use] extern crate log;
 extern crate rustc;
 extern crate rustc_errors;
 extern crate rustc_target;
index 6fc0ed47b807b9de89d03f3197ab6bafc39074f2..8bc0b4969b8f985f439e855f79b6919e8648657a 100644 (file)
@@ -3,7 +3,7 @@
 > WARNING: This README is more or less obsolete, and will be removed
 > soon! The new system is described in the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html
+[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
 
 This pass has the job of enforcing memory safety. This is a subtle
 topic. This docs aim to explain both the practice and the theory
index 684fd10c8c652df33fa0f9069c59e05249d52027..500903c1c3b5ed22831e476e8cc2075ca78b08a5 100644 (file)
@@ -680,7 +680,7 @@ pub fn report_use_of_moved_value(&self,
                 let mut err = self.cannot_act_on_moved_value(use_span,
                                                              verb,
                                                              msg,
-                                                             &format!("{}", nl),
+                                                             Some(format!("{}", nl)),
                                                              Origin::Ast);
                 let need_note = match lp.ty.sty {
                     ty::TypeVariants::TyClosure(id, _) => {
index a5d04c5c576b22e3c2d89e0c611ec58da7f88372..429acbbe0c2cb1cb428447c55e22845378bcfa14 100644 (file)
@@ -98,6 +98,11 @@ pub fn set_probestack(cx: &CodegenCx, llfn: ValueRef) {
         return;
     }
 
+    // probestack doesn't play nice either with gcov profiling.
+    if cx.sess().opts.debugging_opts.profile {
+        return;
+    }
+
     // Flag our internal `__rust_probestack` function as the stack probe symbol.
     // This is defined in the `compiler-builtins` crate for each architecture.
     llvm::AddFunctionAttrStringValue(
index 57cc33d09bbea94e1f36f7fa1c82fe58ae831ce5..94776f17c7989074aea7cf6b89a75776788d76dd 100644 (file)
@@ -48,8 +48,3 @@ fn main() {
 "##,
 
 }
-
-
-register_diagnostics! {
-    E0558
-}
index 990dc66c66a3c8829b4e57a4881e84a21358e667..df34891ff033b0c6afd159aea7f244c412970936 100644 (file)
@@ -91,13 +91,14 @@ struct Node<O> {
     obligation: O,
     state: Cell<NodeState>,
 
-    /// Obligations that depend on this obligation for their
-    /// completion. They must all be in a non-pending state.
-    dependents: Vec<NodeIndex>,
     /// The parent of a node - the original obligation of
     /// which it is a subobligation. Except for error reporting,
-    /// this is just another member of `dependents`.
+    /// it is just like any member of `dependents`.
     parent: Option<NodeIndex>,
+
+    /// Obligations that depend on this obligation for their
+    /// completion. They must all be in a non-pending state.
+    dependents: Vec<NodeIndex>,
 }
 
 /// The state of one node in some tree within the forest. This
@@ -193,15 +194,18 @@ fn register_obligation_at(&mut self, obligation: O, parent: Option<NodeIndex>)
             Entry::Occupied(o) => {
                 debug!("register_obligation_at({:?}, {:?}) - duplicate of {:?}!",
                        obligation, parent, o.get());
+                let node = &mut self.nodes[o.get().get()];
                 if let Some(parent) = parent {
-                    if self.nodes[o.get().get()].dependents.contains(&parent) {
-                        debug!("register_obligation_at({:?}, {:?}) - duplicate subobligation",
-                               obligation, parent);
-                    } else {
-                        self.nodes[o.get().get()].dependents.push(parent);
+                    // If the node is already in `waiting_cache`, it's already
+                    // been marked with a parent. (It's possible that parent
+                    // has been cleared by `apply_rewrites`, though.) So just
+                    // dump `parent` into `node.dependents`... unless it's
+                    // already in `node.dependents` or `node.parent`.
+                    if !node.dependents.contains(&parent) && Some(parent) != node.parent {
+                        node.dependents.push(parent);
                     }
                 }
-                if let NodeState::Error = self.nodes[o.get().get()].state.get() {
+                if let NodeState::Error = node.state.get() {
                     Err(())
                 } else {
                     Ok(())
@@ -380,10 +384,7 @@ fn find_cycles_from_node<P>(&self, stack: &mut Vec<usize>,
             NodeState::Success => {
                 node.state.set(NodeState::OnDfsStack);
                 stack.push(index);
-                if let Some(parent) = node.parent {
-                    self.find_cycles_from_node(stack, processor, parent.get());
-                }
-                for dependent in &node.dependents {
+                for dependent in node.parent.iter().chain(node.dependents.iter()) {
                     self.find_cycles_from_node(stack, processor, dependent.get());
                 }
                 stack.pop();
@@ -427,7 +428,7 @@ fn error_at(&mut self, p: usize) -> Vec<O> {
             }
 
             error_stack.extend(
-                node.dependents.iter().cloned().chain(node.parent).map(|x| x.get())
+                node.parent.iter().chain(node.dependents.iter()).map(|x| x.get())
             );
         }
 
@@ -437,11 +438,7 @@ fn error_at(&mut self, p: usize) -> Vec<O> {
 
     #[inline]
     fn mark_neighbors_as_waiting_from(&self, node: &Node<O>) {
-        if let Some(parent) = node.parent {
-            self.mark_as_waiting_from(&self.nodes[parent.get()]);
-        }
-
-        for dependent in &node.dependents {
+        for dependent in node.parent.iter().chain(node.dependents.iter()) {
             self.mark_as_waiting_from(&self.nodes[dependent.get()]);
         }
     }
@@ -588,8 +585,8 @@ impl<O> Node<O> {
     fn new(parent: Option<NodeIndex>, obligation: O) -> Node<O> {
         Node {
             obligation,
-            parent,
             state: Cell::new(NodeState::Pending),
+            parent,
             dependents: vec![],
         }
     }
index c18a089268659e06668c04083748f609239539f9..feeac9d938b6a4b01a352293d6fa54b0a355d2b6 100644 (file)
@@ -1051,10 +1051,19 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(
         });
     }
 
+    // Expand global allocators, which are treated as an in-tree proc macro
     krate = time(sess, "creating allocators", || {
-        allocator::expand::modify(&sess.parse_sess, &mut resolver, krate, sess.diagnostic())
+        allocator::expand::modify(
+            &sess.parse_sess,
+            &mut resolver,
+            krate,
+            crate_name.to_string(),
+            sess.diagnostic(),
+        )
     });
 
+    // Done with macro expansion!
+
     after_expand(&krate)?;
 
     if sess.opts.debugging_opts.input_stats {
index f1ad14237eec27dfeb7ee1ce1cf424a46db56895..38ecbf5ca8ada5000191815c96870f7980a02c5a 100644 (file)
@@ -677,14 +677,20 @@ fn involves_impl_trait(ty: &ast::Ty) -> bool {
                     ast::TyKind::Paren(ref subty) => involves_impl_trait(subty),
                     ast::TyKind::Tup(ref tys) => any_involves_impl_trait(tys.iter()),
                     ast::TyKind::Path(_, ref path) => path.segments.iter().any(|seg| {
-                        match seg.parameters.as_ref().map(|p| &**p) {
+                        match seg.args.as_ref().map(|generic_arg| &**generic_arg) {
                             None => false,
-                            Some(&ast::PathParameters::AngleBracketed(ref data)) =>
-                                any_involves_impl_trait(data.types.iter()) ||
-                                any_involves_impl_trait(data.bindings.iter().map(|b| &b.ty)),
-                            Some(&ast::PathParameters::Parenthesized(ref data)) =>
+                            Some(&ast::GenericArgs::AngleBracketed(ref data)) => {
+                                let types = data.args.iter().filter_map(|arg| match arg {
+                                    ast::GenericArg::Type(ty) => Some(ty),
+                                    _ => None,
+                                });
+                                any_involves_impl_trait(types.into_iter()) ||
+                                any_involves_impl_trait(data.bindings.iter().map(|b| &b.ty))
+                            },
+                            Some(&ast::GenericArgs::Parenthesized(ref data)) => {
                                 any_involves_impl_trait(data.inputs.iter()) ||
-                                any_involves_impl_trait(data.output.iter()),
+                                any_involves_impl_trait(data.output.iter())
+                            }
                         }
                     }),
                     _ => false,
@@ -706,8 +712,8 @@ impl<'a> fold::Folder for ReplaceBodyWithLoop<'a> {
     fn fold_item_kind(&mut self, i: ast::ItemKind) -> ast::ItemKind {
         let is_const = match i {
             ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => true,
-            ast::ItemKind::Fn(ref decl, _, ref constness, _, _, _) =>
-                constness.node == ast::Constness::Const || Self::should_ignore_fn(decl),
+            ast::ItemKind::Fn(ref decl, ref header, _, _) =>
+                header.constness.node == ast::Constness::Const || Self::should_ignore_fn(decl),
             _ => false,
         };
         self.run(is_const, |s| fold::noop_fold_item_kind(i, s))
@@ -716,8 +722,8 @@ fn fold_item_kind(&mut self, i: ast::ItemKind) -> ast::ItemKind {
     fn fold_trait_item(&mut self, i: ast::TraitItem) -> SmallVector<ast::TraitItem> {
         let is_const = match i.node {
             ast::TraitItemKind::Const(..) => true,
-            ast::TraitItemKind::Method(ast::MethodSig { ref decl, ref constness, .. }, _) =>
-                constness.node == ast::Constness::Const || Self::should_ignore_fn(decl),
+            ast::TraitItemKind::Method(ast::MethodSig { ref decl, ref header, .. }, _) =>
+                header.constness.node == ast::Constness::Const || Self::should_ignore_fn(decl),
             _ => false,
         };
         self.run(is_const, |s| fold::noop_fold_trait_item(i, s))
@@ -726,8 +732,8 @@ fn fold_trait_item(&mut self, i: ast::TraitItem) -> SmallVector<ast::TraitItem>
     fn fold_impl_item(&mut self, i: ast::ImplItem) -> SmallVector<ast::ImplItem> {
         let is_const = match i.node {
             ast::ImplItemKind::Const(..) => true,
-            ast::ImplItemKind::Method(ast::MethodSig { ref decl, ref constness, .. }, _) =>
-                constness.node == ast::Constness::Const || Self::should_ignore_fn(decl),
+            ast::ImplItemKind::Method(ast::MethodSig { ref decl, ref header, .. }, _) =>
+                header.constness.node == ast::Constness::Const || Self::should_ignore_fn(decl),
             _ => false,
         };
         self.run(is_const, |s| fold::noop_fold_impl_item(i, s))
index dbf756f80ca3853bb492549b8213171dd29139bb..1b5361187f36a4b016903512588ebb0a0f7f3152 100644 (file)
@@ -18,7 +18,7 @@
 use syntax::attr;
 use syntax_pos::Span;
 
-use rustc::hir::{self, PatKind};
+use rustc::hir::{self, GenericParamKind, PatKind};
 use rustc::hir::intravisit::FnKind;
 
 #[derive(PartialEq)]
@@ -147,9 +147,12 @@ fn check_variant(&mut self, cx: &LateContext, v: &hir::Variant, _: &hir::Generic
     }
 
     fn check_generic_param(&mut self, cx: &LateContext, param: &hir::GenericParam) {
-        if let hir::GenericParam::Type(ref gen) = *param {
-            if gen.synthetic.is_none() {
-                self.check_case(cx, "type parameter", gen.name, gen.span);
+        match param.kind {
+            GenericParamKind::Lifetime { .. } => {}
+            GenericParamKind::Type { synthetic, .. } => {
+                if synthetic.is_none() {
+                    self.check_case(cx, "type parameter", param.name.name(), param.span);
+                }
             }
         }
     }
@@ -253,13 +256,12 @@ fn check_crate(&mut self, cx: &LateContext, cr: &hir::Crate) {
     }
 
     fn check_generic_param(&mut self, cx: &LateContext, param: &hir::GenericParam) {
-        if let hir::GenericParam::Lifetime(ref ld) = *param {
-            self.check_snake_case(
-                cx,
-                "lifetime",
-                &ld.lifetime.name.name().as_str(),
-                Some(ld.lifetime.span)
-            );
+        match param.kind {
+            GenericParamKind::Lifetime { .. } => {
+                let name = param.name.name().as_str();
+                self.check_snake_case(cx, "lifetime", &name, Some(param.span));
+            }
+            GenericParamKind::Type { .. } => {}
         }
     }
 
@@ -282,9 +284,9 @@ fn check_fn(&mut self,
                     _ => (),
                 }
             }
-            FnKind::ItemFn(name, _, _, _, abi, _, attrs) => {
+            FnKind::ItemFn(name, _, header, _, attrs) => {
                 // Skip foreign-ABI #[no_mangle] functions (Issue #31924)
-                if abi != Abi::Rust && attr::find_by_name(attrs, "no_mangle").is_some() {
+                if header.abi != Abi::Rust && attr::find_by_name(attrs, "no_mangle").is_some() {
                     return;
                 }
                 self.check_snake_case(cx, "function", &name.as_str(), Some(span))
index 79796d788719a7be3a7cc78583f63cb3110a2ae7..d6120ab207924b2206a05eab6d4f45e29c716bd9 100644 (file)
@@ -49,7 +49,7 @@
 use syntax::symbol::keywords;
 use syntax::errors::{Applicability, DiagnosticBuilder};
 
-use rustc::hir::{self, PatKind};
+use rustc::hir::{self, GenericParamKind, PatKind};
 use rustc::hir::intravisit::FnKind;
 
 use bad_style::{MethodLateContext, method_context};
@@ -259,12 +259,12 @@ fn check_fn(&mut self,
                 span: Span,
                 _: ast::NodeId) {
         match fk {
-            FnKind::ItemFn(_, _, hir::Unsafety::Unsafe, ..) => {
+            FnKind::ItemFn(_, _, hir::FnHeader { unsafety: hir::Unsafety::Unsafe, .. }, ..) => {
                 self.report_unsafe(cx, span, "declaration of an `unsafe` function")
             }
 
             FnKind::Method(_, sig, ..) => {
-                if sig.unsafety == hir::Unsafety::Unsafe {
+                if sig.header.unsafety == hir::Unsafety::Unsafe {
                     self.report_unsafe(cx, span, "implementation of an `unsafe` method")
                 }
             }
@@ -275,7 +275,7 @@ fn check_fn(&mut self,
 
     fn check_trait_item(&mut self, cx: &LateContext, item: &hir::TraitItem) {
         if let hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(_)) = item.node {
-            if sig.unsafety == hir::Unsafety::Unsafe {
+            if sig.header.unsafety == hir::Unsafety::Unsafe {
                 self.report_unsafe(cx, item.span, "declaration of an `unsafe` method")
             }
         }
@@ -1196,15 +1196,21 @@ fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
                         }
                         err.emit();
                     }
-                    if generics.is_type_parameterized() {
-                        let mut err = cx.struct_span_lint(NO_MANGLE_GENERIC_ITEMS,
-                                                          it.span,
-                                                          "functions generic over \
-                                                           types must be mangled");
-                        err.span_suggestion_short(no_mangle_attr.span,
-                                                  "remove this attribute",
-                                                  "".to_owned());
-                        err.emit();
+                    for param in &generics.params {
+                        match param.kind {
+                            GenericParamKind::Lifetime { .. } => {}
+                            GenericParamKind::Type { .. } => {
+                                let mut err = cx.struct_span_lint(NO_MANGLE_GENERIC_ITEMS,
+                                                                  it.span,
+                                                                  "functions generic over \
+                                                                   types must be mangled");
+                                err.span_suggestion_short(no_mangle_attr.span,
+                                                          "remove this attribute",
+                                                          "".to_owned());
+                                err.emit();
+                                break;
+                            }
+                        }
                     }
                 }
             }
@@ -1531,10 +1537,7 @@ fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
         }
         // The parameters must not have bounds
         for param in type_alias_generics.params.iter() {
-            let spans : Vec<_> = match param {
-                &hir::GenericParam::Lifetime(ref l) => l.bounds.iter().map(|b| b.span).collect(),
-                &hir::GenericParam::Type(ref ty) => ty.bounds.iter().map(|b| b.span()).collect(),
-            };
+            let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
             if !spans.is_empty() {
                 let mut err = cx.struct_span_lint(
                     TYPE_ALIAS_BOUNDS,
index f84bfd66a6368904a72901494bb66534e3d9448b..11bca9b4a2d0b00d0c073612ab5f5900ab020075 100644 (file)
@@ -280,6 +280,11 @@ macro_rules! add_lint_group {
             reference: "issue TBD",
             edition: Some(Edition::Edition2018),
         },
+        FutureIncompatibleInfo {
+            id: LintId::of(WHERE_CLAUSES_OBJECT_SAFETY),
+            reference: "issue #51443 <https://github.com/rust-lang/rust/issues/51443>",
+            edition: None,
+        },
         FutureIncompatibleInfo {
             id: LintId::of(DUPLICATE_ASSOCIATED_TYPE_BINDINGS),
             reference: "issue #50589 <https://github.com/rust-lang/rust/issues/50589>",
index 2abe361233fd0f3fe77189a7f2fa6449f188d948..50492ae073720b62fef99564f6df441697fa2407 100644 (file)
@@ -810,52 +810,63 @@ fn get_lints(&self) -> LintArray {
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
     fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
-        if let hir::ItemEnum(ref enum_definition, ref gens) = it.node {
-            if gens.params.iter().all(|param| param.is_lifetime_param()) {
-                // sizes only make sense for non-generic types
-                let item_def_id = cx.tcx.hir.local_def_id(it.id);
-                let t = cx.tcx.type_of(item_def_id);
-                let ty = cx.tcx.erase_regions(&t);
-                let layout = cx.layout_of(ty).unwrap_or_else(|e| {
-                    bug!("failed to get layout for `{}`: {}", t, e)
-                });
-
-                if let layout::Variants::Tagged { ref variants, ref tag, .. } = layout.variants {
-                    let discr_size = tag.value.size(cx.tcx).bytes();
-
-                    debug!("enum `{}` is {} bytes large with layout:\n{:#?}",
-                      t, layout.size.bytes(), layout);
-
-                    let (largest, slargest, largest_index) = enum_definition.variants
-                        .iter()
-                        .zip(variants)
-                        .map(|(variant, variant_layout)| {
-                            // Subtract the size of the enum discriminant
-                            let bytes = variant_layout.size.bytes()
-                                .saturating_sub(discr_size);
-
-                            debug!("- variant `{}` is {} bytes large", variant.node.name, bytes);
-                            bytes
-                        })
-                        .enumerate()
-                        .fold((0, 0, 0), |(l, s, li), (idx, size)| if size > l {
-                            (size, l, idx)
-                        } else if size > s {
-                            (l, size, li)
-                        } else {
-                            (l, s, li)
-                        });
-
-                    // we only warn if the largest variant is at least thrice as large as
-                    // the second-largest.
-                    if largest > slargest * 3 && slargest > 0 {
-                        cx.span_lint(VARIANT_SIZE_DIFFERENCES,
-                                     enum_definition.variants[largest_index].span,
-                                     &format!("enum variant is more than three times larger \
-                                               ({} bytes) than the next largest",
-                                              largest));
+        if let hir::ItemEnum(ref enum_definition, _) = it.node {
+            let item_def_id = cx.tcx.hir.local_def_id(it.id);
+            let generics = cx.tcx.generics_of(item_def_id);
+            for param in &generics.params {
+                match param.kind {
+                    ty::GenericParamDefKind::Lifetime { .. } => {},
+                    ty::GenericParamDefKind::Type { .. } => return,
+                }
+            }
+            // Sizes only make sense for non-generic types.
+            let t = cx.tcx.type_of(item_def_id);
+            let ty = cx.tcx.erase_regions(&t);
+            match cx.layout_of(ty) {
+                Ok(layout) => {
+                    let variants = &layout.variants;
+                    if let layout::Variants::Tagged { ref variants, ref tag, .. } = variants {
+                        let discr_size = tag.value.size(cx.tcx).bytes();
+
+                        debug!("enum `{}` is {} bytes large with layout:\n{:#?}",
+                               t, layout.size.bytes(), layout);
+
+                        let (largest, slargest, largest_index) = enum_definition.variants
+                            .iter()
+                            .zip(variants)
+                            .map(|(variant, variant_layout)| {
+                                // Subtract the size of the enum discriminant.
+                                let bytes = variant_layout.size.bytes().saturating_sub(discr_size);
+
+                                debug!("- variant `{}` is {} bytes large",
+                                       variant.node.name,
+                                       bytes);
+                                bytes
+                            })
+                            .enumerate()
+                            .fold((0, 0, 0), |(l, s, li), (idx, size)| if size > l {
+                                (size, l, idx)
+                            } else if size > s {
+                                (l, size, li)
+                            } else {
+                                (l, s, li)
+                            });
+
+                        // We only warn if the largest variant is at least thrice as large as
+                        // the second-largest.
+                        if largest > slargest * 3 && slargest > 0 {
+                            cx.span_lint(VARIANT_SIZE_DIFFERENCES,
+                                            enum_definition.variants[largest_index].span,
+                                            &format!("enum variant is more than three times \
+                                                      larger ({} bytes) than the next largest",
+                                                     largest));
+                        }
                     }
                 }
+                Err(ty::layout::LayoutError::Unknown(_)) => return,
+                Err(err @ ty::layout::LayoutError::SizeOverflow(_)) => {
+                    bug!("failed to get layout for `{}`: {}", t, err);
+                }
             }
         }
     }
index 6c1991457433f6231b445ea18632501afff5bdc7..1a13335a0e49d34bfc44b62f02b7011ecd4126b1 100644 (file)
@@ -570,7 +570,7 @@ fn register_bang_proc_macro(&mut self,
                                         name: &str,
                                         expand: fn(TokenStream) -> TokenStream) {
                 let expand = SyntaxExtension::ProcMacro(
-                    Box::new(BangProcMacro { inner: expand }), self.edition
+                    Box::new(BangProcMacro { inner: expand }), false, self.edition
                 );
                 self.extensions.push((Symbol::intern(name), Lrc::new(expand)));
             }
index b33d97cb1ee9f7988d17e99bd8bf72f71ba75e64..d0e4e54e63d677f86f615ff5004b4620d3c5b644 100644 (file)
@@ -519,7 +519,7 @@ fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
         } else if data.name == "proc_macro" &&
                   self.get_crate_data(id.krate).item_name(id.index) == "quote" {
             let ext = SyntaxExtension::ProcMacro(Box::new(::proc_macro::__internal::Quoter),
-                                                 data.root.edition);
+                                                 true, data.root.edition);
             return LoadedMacro::ProcMacro(Lrc::new(ext));
         }
 
index 33d4df1c3a5dc2b37984615144fc81cd22ba15fa..ce270006a9d0ad187d1a1e213363238804dbc545 100644 (file)
@@ -917,7 +917,7 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
             ty::AssociatedKind::Method => {
                 let fn_data = if let hir::ImplItemKind::Method(ref sig, body) = ast_item.node {
                     FnData {
-                        constness: sig.constness,
+                        constness: sig.header.constness,
                         arg_names: self.encode_fn_arg_names_for_body(body),
                         sig: self.lazy(&tcx.fn_sig(def_id)),
                     }
@@ -941,7 +941,7 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
                     let needs_inline = (generics.requires_monomorphization(self.tcx) ||
                                         tcx.codegen_fn_attrs(def_id).requests_inline()) &&
                                         !self.metadata_output_only();
-                    let is_const_fn = sig.constness == hir::Constness::Const;
+                    let is_const_fn = sig.header.constness == hir::Constness::Const;
                     let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
                     needs_inline || is_const_fn || always_encode_mir
                 },
@@ -1045,9 +1045,9 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
                     self.encode_rendered_const_for_body(body_id)
                 )
             }
-            hir::ItemFn(_, _, constness, .., body) => {
+            hir::ItemFn(_, header, .., body) => {
                 let data = FnData {
-                    constness,
+                    constness: header.constness,
                     arg_names: self.encode_fn_arg_names_for_body(body),
                     sig: self.lazy(&tcx.fn_sig(def_id)),
                 };
@@ -1235,13 +1235,20 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
                     self.encode_optimized_mir(def_id)
                 }
                 hir::ItemConst(..) => self.encode_optimized_mir(def_id),
-                hir::ItemFn(_, _, constness, _, ref generics, _) => {
-                    let has_tps = generics.ty_params().next().is_some();
+                hir::ItemFn(_, header, ..) => {
+                    let generics = tcx.generics_of(def_id);
+                    let has_types = generics.params.iter().any(|param| match param.kind {
+                        ty::GenericParamDefKind::Type { .. } => true,
+                        _ => false,
+                    });
                     let needs_inline =
-                        (has_tps || tcx.codegen_fn_attrs(def_id).requests_inline()) &&
+                        (has_types || tcx.codegen_fn_attrs(def_id).requests_inline()) &&
                             !self.metadata_output_only();
                     let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
-                    if needs_inline || constness == hir::Constness::Const || always_encode_mir {
+                    if needs_inline
+                        || header.constness == hir::Constness::Const
+                        || always_encode_mir
+                    {
                         self.encode_optimized_mir(def_id)
                     } else {
                         None
@@ -1645,11 +1652,15 @@ fn encode_fields(&mut self, adt_def_id: DefId) {
     }
 
     fn encode_info_for_generics(&mut self, generics: &hir::Generics) {
-        for ty_param in generics.ty_params() {
-            let def_id = self.tcx.hir.local_def_id(ty_param.id);
-            let has_default = Untracked(ty_param.default.is_some());
-            self.record(def_id, IsolatedEncoder::encode_info_for_ty_param, (def_id, has_default));
-        }
+        generics.params.iter().for_each(|param| match param.kind {
+            hir::GenericParamKind::Lifetime { .. } => {}
+            hir::GenericParamKind::Type { ref default, .. } => {
+                let def_id = self.tcx.hir.local_def_id(param.id);
+                let has_default = Untracked(default.is_some());
+                let encode_info = IsolatedEncoder::encode_info_for_ty_param;
+                self.record(def_id, encode_info, (def_id, has_default));
+            }
+        });
     }
 
     fn encode_info_for_ty(&mut self, ty: &hir::Ty) {
index 30be87199ebe09f0968d84c293f0449017ce095f..44fc67dfa437959e869863a4c244db732cf81069 100644 (file)
@@ -52,7 +52,7 @@ pub(super) fn report_use_of_moved_or_uninitialized(
 
             self.moved_error_reported.insert(root_place.clone());
 
-            let item_msg = match self.describe_place(place) {
+            let item_msg = match self.describe_place_with_options(place, IncludingDowncast(true)) {
                 Some(name) => format!("`{}`", name),
                 None => "value".to_owned(),
             };
@@ -60,7 +60,9 @@ pub(super) fn report_use_of_moved_or_uninitialized(
                 .cannot_act_on_uninitialized_variable(
                     span,
                     desired_action.as_noun(),
-                    &self.describe_place(place).unwrap_or("_".to_owned()),
+                    &self
+                        .describe_place_with_options(place, IncludingDowncast(true))
+                        .unwrap_or("_".to_owned()),
                     Origin::Mir,
                 )
                 .span_label(span, format!("use of possibly uninitialized {}", item_msg))
@@ -72,14 +74,17 @@ pub(super) fn report_use_of_moved_or_uninitialized(
                 span,
                 desired_action.as_noun(),
                 msg,
-                &self.describe_place(place).unwrap_or("_".to_owned()),
+                self.describe_place_with_options(&place, IncludingDowncast(true)),
                 Origin::Mir,
             );
 
             let mut is_loop_move = false;
-            for moi in mois {
+            for moi in &mois {
                 let move_msg = ""; //FIXME: add " (into closure)"
-                let move_span = self.mir.source_info(self.move_data.moves[*moi].source).span;
+                let move_span = self
+                    .mir
+                    .source_info(self.move_data.moves[**moi].source)
+                    .span;
                 if span == move_span {
                     err.span_label(
                         span,
@@ -116,16 +121,23 @@ pub(super) fn report_use_of_moved_or_uninitialized(
                 };
 
                 if needs_note {
-                    let note_msg = match self.describe_place(place) {
-                        Some(name) => format!("`{}`", name),
-                        None => "value".to_owned(),
-                    };
+                    let mpi = self.move_data.moves[*mois[0]].path;
+                    let place = &self.move_data.move_paths[mpi].place;
+
+                    if let Some(ty) = self.retrieve_type_for_place(place) {
+                        let note_msg = match self
+                            .describe_place_with_options(place, IncludingDowncast(true))
+                        {
+                            Some(name) => format!("`{}`", name),
+                            None => "value".to_owned(),
+                        };
 
-                    err.note(&format!(
-                        "move occurs because {} has type `{}`, \
-                         which does not implement the `Copy` trait",
-                        note_msg, ty
-                    ));
+                        err.note(&format!(
+                            "move occurs because {} has type `{}`, \
+                             which does not implement the `Copy` trait",
+                            note_msg, ty
+                        ));
+                    }
                 }
             }
 
@@ -644,8 +656,10 @@ pub(super) fn report_illegal_reassignment(
             let local_decl = &self.mir.local_decls[*local];
             if let Some(name) = local_decl.name {
                 if local_decl.can_be_made_mutable() {
-                    err.span_label(local_decl.source_info.span,
-                                   format!("consider changing this to `mut {}`", name));
+                    err.span_label(
+                        local_decl.source_info.span,
+                        format!("consider changing this to `mut {}`", name),
+                    );
                 }
             }
         }
@@ -654,12 +668,26 @@ pub(super) fn report_illegal_reassignment(
     }
 }
 
+pub(super) struct IncludingDowncast(bool);
+
 impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
     // End-user visible description of `place` if one can be found. If the
     // place is a temporary for instance, None will be returned.
     pub(super) fn describe_place(&self, place: &Place<'tcx>) -> Option<String> {
+        self.describe_place_with_options(place, IncludingDowncast(false))
+    }
+
+    // End-user visible description of `place` if one can be found. If the
+    // place is a temporary for instance, None will be returned.
+    // `IncludingDowncast` parameter makes the function return `Err` if `ProjectionElem` is
+    // `Downcast` and `IncludingDowncast` is true
+    pub(super) fn describe_place_with_options(
+        &self,
+        place: &Place<'tcx>,
+        including_downcast: IncludingDowncast,
+    ) -> Option<String> {
         let mut buf = String::new();
-        match self.append_place_to_string(place, &mut buf, false) {
+        match self.append_place_to_string(place, &mut buf, false, &including_downcast) {
             Ok(()) => Some(buf),
             Err(()) => None,
         }
@@ -671,6 +699,7 @@ fn append_place_to_string(
         place: &Place<'tcx>,
         buf: &mut String,
         mut autoderef: bool,
+        including_downcast: &IncludingDowncast,
     ) -> Result<(), ()> {
         match *place {
             Place::Local(local) => {
@@ -692,15 +721,33 @@ fn append_place_to_string(
                             }
                         } else {
                             if autoderef {
-                                self.append_place_to_string(&proj.base, buf, autoderef)?;
+                                self.append_place_to_string(
+                                    &proj.base,
+                                    buf,
+                                    autoderef,
+                                    &including_downcast,
+                                )?;
                             } else {
                                 buf.push_str(&"*");
-                                self.append_place_to_string(&proj.base, buf, autoderef)?;
+                                self.append_place_to_string(
+                                    &proj.base,
+                                    buf,
+                                    autoderef,
+                                    &including_downcast,
+                                )?;
                             }
                         }
                     }
                     ProjectionElem::Downcast(..) => {
-                        self.append_place_to_string(&proj.base, buf, autoderef)?;
+                        self.append_place_to_string(
+                            &proj.base,
+                            buf,
+                            autoderef,
+                            &including_downcast,
+                        )?;
+                        if including_downcast.0 {
+                            return Err(());
+                        }
                     }
                     ProjectionElem::Field(field, _ty) => {
                         autoderef = true;
@@ -711,14 +758,24 @@ fn append_place_to_string(
                             buf.push_str(&name);
                         } else {
                             let field_name = self.describe_field(&proj.base, field);
-                            self.append_place_to_string(&proj.base, buf, autoderef)?;
+                            self.append_place_to_string(
+                                &proj.base,
+                                buf,
+                                autoderef,
+                                &including_downcast,
+                            )?;
                             buf.push_str(&format!(".{}", field_name));
                         }
                     }
                     ProjectionElem::Index(index) => {
                         autoderef = true;
 
-                        self.append_place_to_string(&proj.base, buf, autoderef)?;
+                        self.append_place_to_string(
+                            &proj.base,
+                            buf,
+                            autoderef,
+                            &including_downcast,
+                        )?;
                         buf.push_str("[");
                         if let Err(_) = self.append_local_to_string(index, buf) {
                             buf.push_str("..");
@@ -730,7 +787,12 @@ fn append_place_to_string(
                         // Since it isn't possible to borrow an element on a particular index and
                         // then use another while the borrow is held, don't output indices details
                         // to avoid confusing the end-user
-                        self.append_place_to_string(&proj.base, buf, autoderef)?;
+                        self.append_place_to_string(
+                            &proj.base,
+                            buf,
+                            autoderef,
+                            &including_downcast,
+                        )?;
                         buf.push_str(&"[..]");
                     }
                 };
index 3d3275a6b171485ae18cbd47e75ef9a69f16b782..6d77364aae02a6b783beceef0339cf6aec44e611 100644 (file)
 use rustc::hir::def_id::DefId;
 use rustc::hir::map::definitions::DefPathData;
 use rustc::infer::InferCtxt;
-use rustc::ty::{self, ParamEnv, TyCtxt};
-use rustc::ty::query::Providers;
 use rustc::lint::builtin::UNUSED_MUT;
 use rustc::mir::{self, AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
-use rustc::mir::{ClearCrossCrate, Local, Location, Place, Mir, Mutability, Operand};
-use rustc::mir::{Projection, ProjectionElem, Rvalue, Field, Statement, StatementKind};
+use rustc::mir::{ClearCrossCrate, Local, Location, Mir, Mutability, Operand, Place};
+use rustc::mir::{Field, Projection, ProjectionElem, Rvalue, Statement, StatementKind};
 use rustc::mir::{Terminator, TerminatorKind};
+use rustc::ty::query::Providers;
+use rustc::ty::{self, ParamEnv, TyCtxt};
 
 use rustc_data_structures::control_flow_graph::dominators::Dominators;
 use rustc_data_structures::fx::FxHashSet;
 
 use syntax_pos::Span;
 
-use dataflow::{do_dataflow, DebugFormatted};
+use dataflow::indexes::BorrowIndex;
+use dataflow::move_paths::{HasMoveData, LookupResult, MoveData, MovePathIndex};
+use dataflow::move_paths::{IllegalMoveOriginKind, MoveError};
+use dataflow::Borrows;
+use dataflow::DataflowResultsConsumer;
 use dataflow::FlowAtLocation;
 use dataflow::MoveDataParamEnv;
-use dataflow::{DataflowResultsConsumer};
-use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
+use dataflow::{do_dataflow, DebugFormatted};
 use dataflow::{EverInitializedPlaces, MovingOutStatements};
-use dataflow::Borrows;
-use dataflow::indexes::BorrowIndex;
-use dataflow::move_paths::{IllegalMoveOriginKind, MoveError};
-use dataflow::move_paths::{HasMoveData, LookupResult, MoveData, MovePathIndex};
+use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
 use util::borrowck_errors::{BorrowckErrors, Origin};
 use util::collect_writes::FindAssignments;
 
-use self::borrow_set::{BorrowSet, BorrowData};
+use self::borrow_set::{BorrowData, BorrowSet};
 use self::flows::Flows;
 use self::location::LocationTable;
 use self::prefixes::PrefixSet;
 mod error_reporting;
 mod flows;
 mod location;
+mod path_utils;
 crate mod place_ext;
 mod prefixes;
-mod path_utils;
+mod used_muts;
 
 pub(crate) mod nll;
 
@@ -71,10 +72,7 @@ pub fn provide(providers: &mut Providers) {
     };
 }
 
-fn mir_borrowck<'a, 'tcx>(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    def_id: DefId,
-) -> BorrowCheckResult<'tcx> {
+fn mir_borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> BorrowCheckResult<'tcx> {
     let input_mir = tcx.mir_validated(def_id);
     debug!("run query mir_borrowck: {}", tcx.item_path_str(def_id));
 
@@ -102,7 +100,8 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
     let tcx = infcx.tcx;
     let attributes = tcx.get_attrs(def_id);
     let param_env = tcx.param_env(def_id);
-    let id = tcx.hir
+    let id = tcx
+        .hir
         .as_local_node_id(def_id)
         .expect("do_mir_borrowck: non-local DefId");
 
@@ -137,9 +136,10 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
                         // borrow to provide feedback about why this
                         // was a move rather than a copy.
                         match ty.sty {
-                            ty::TyArray(..) | ty::TySlice(..) =>
-                                tcx.cannot_move_out_of_interior_noncopy(span, ty, None, origin),
-                            _ => tcx.cannot_move_out_of(span, "borrowed content", origin)
+                            ty::TyArray(..) | ty::TySlice(..) => {
+                                tcx.cannot_move_out_of_interior_noncopy(span, ty, None, origin)
+                            }
+                            _ => tcx.cannot_move_out_of(span, "borrowed content", origin),
                         }
                     }
                     IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
@@ -276,29 +276,21 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
     // Note that this set is expected to be small - only upvars from closures
     // would have a chance of erroneously adding non-user-defined mutable vars
     // to the set.
-    let temporary_used_locals: FxHashSet<Local> =
-        mbcx.used_mut.iter()
-            .filter(|&local| !mbcx.mir.local_decls[*local].is_user_variable.is_some())
-            .cloned()
-            .collect();
-
-    for local in temporary_used_locals {
-        for location in mbcx.mir.find_assignments(local) {
-            for moi in &mbcx.move_data.loc_map[location] {
-                let mpi = &mbcx.move_data.moves[*moi].path;
-                let path = &mbcx.move_data.move_paths[*mpi];
-                debug!("assignment of {:?} to {:?}, adding {:?} to used mutable set",
-                       path.place, local, path.place);
-                if let Place::Local(user_local) = path.place {
-                    mbcx.used_mut.insert(user_local);
-                }
-            }
-        }
-    }
+    let temporary_used_locals: FxHashSet<Local> = mbcx
+        .used_mut
+        .iter()
+        .filter(|&local| !mbcx.mir.local_decls[*local].is_user_variable.is_some())
+        .cloned()
+        .collect();
+    mbcx.gather_used_muts(temporary_used_locals);
 
     debug!("mbcx.used_mut: {:?}", mbcx.used_mut);
 
-    for local in mbcx.mir.mut_vars_and_args_iter().filter(|local| !mbcx.used_mut.contains(local)) {
+    for local in mbcx
+        .mir
+        .mut_vars_and_args_iter()
+        .filter(|local| !mbcx.used_mut.contains(local))
+    {
         if let ClearCrossCrate::Set(ref vsi) = mbcx.mir.source_scope_local_data {
             let local_decl = &mbcx.mir.local_decls[local];
 
@@ -309,7 +301,9 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
 
             // Skip over locals that begin with an underscore or have no name
             match local_decl.name {
-                Some(name) => if name.as_str().starts_with("_") { continue; },
+                Some(name) => if name.as_str().starts_with("_") {
+                    continue;
+                },
                 None => continue,
             }
 
@@ -320,10 +314,9 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
                 UNUSED_MUT,
                 vsi[local_decl.source_info.scope].lint_root,
                 span,
-                "variable does not need to be mutable"
-            )
-            .span_suggestion_short(mut_span, "remove this `mut`", "".to_owned())
-            .emit();
+                "variable does not need to be mutable",
+            ).span_suggestion_short(mut_span, "remove this `mut`", "".to_owned())
+                .emit();
         }
     }
 
@@ -431,12 +424,13 @@ fn visit_statement_entry(
                 );
             }
             StatementKind::ReadForMatch(ref place) => {
-                self.access_place(ContextKind::ReadForMatch.new(location),
-                                  (place, span),
-                                  (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))),
-                                  LocalMutationIsAllowed::No,
-                                  flow_state,
-                                  );
+                self.access_place(
+                    ContextKind::ReadForMatch.new(location),
+                    (place, span),
+                    (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))),
+                    LocalMutationIsAllowed::No,
+                    flow_state,
+                );
             }
             StatementKind::SetDiscriminant {
                 ref place,
@@ -491,10 +485,10 @@ fn visit_statement_entry(
                 // ignored when consuming results (update to
                 // flow_state already handled).
             }
-            StatementKind::Nop |
-            StatementKind::UserAssertTy(..) |
-            StatementKind::Validate(..) |
-            StatementKind::StorageLive(..) => {
+            StatementKind::Nop
+            | StatementKind::UserAssertTy(..)
+            | StatementKind::Validate(..)
+            StatementKind::StorageLive(..) => {
                 // `Nop`, `UserAssertTy`, `Validate`, and `StorageLive` are irrelevant
                 // to borrow check.
             }
@@ -608,11 +602,7 @@ fn visit_terminator_entry(
                 use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
                 if let BoundsCheck { ref len, ref index } = *msg {
                     self.consume_operand(ContextKind::Assert.new(loc), (len, span), flow_state);
-                    self.consume_operand(
-                        ContextKind::Assert.new(loc),
-                        (index, span),
-                        flow_state,
-                    );
+                    self.consume_operand(ContextKind::Assert.new(loc), (index, span), flow_state);
                 }
             }
 
@@ -672,8 +662,8 @@ enum MutateMode {
     WriteAndRead,
 }
 
-use self::ShallowOrDeep::{Deep, Shallow};
 use self::ReadOrWrite::{Activation, Read, Reservation, Write};
+use self::ShallowOrDeep::{Deep, Shallow};
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 enum ArtificialField {
@@ -807,10 +797,8 @@ fn visit_terminator_drop(
         span: Span,
     ) {
         let gcx = self.tcx.global_tcx();
-        let drop_field = |
-            mir: &mut MirBorrowckCtxt<'cx, 'gcx, 'tcx>,
-            (index, field): (usize, ty::Ty<'gcx>),
-        | {
+        let drop_field = |mir: &mut MirBorrowckCtxt<'cx, 'gcx, 'tcx>,
+                          (index, field): (usize, ty::Ty<'gcx>)| {
             let field_ty = gcx.normalize_erasing_regions(mir.param_env, field);
             let place = drop_place.clone().field(Field::new(index), field_ty);
 
@@ -832,23 +820,31 @@ fn visit_terminator_drop(
             }
             // Same as above, but for tuples.
             ty::TyTuple(tys) => {
-                tys.iter().cloned().enumerate()
+                tys.iter()
+                    .cloned()
+                    .enumerate()
                     .for_each(|field| drop_field(self, field));
             }
             // Closures also have disjoint fields, but they are only
             // directly accessed in the body of the closure.
             ty::TyClosure(def, substs)
-                if *drop_place == Place::Local(Local::new(1)) && !self.mir.upvar_decls.is_empty()
-            => {
-                substs.upvar_tys(def, self.tcx).enumerate()
+                if *drop_place == Place::Local(Local::new(1))
+                    && !self.mir.upvar_decls.is_empty() =>
+            {
+                substs
+                    .upvar_tys(def, self.tcx)
+                    .enumerate()
                     .for_each(|field| drop_field(self, field));
             }
             // Generators also have disjoint fields, but they are only
             // directly accessed in the body of the generator.
             ty::TyGenerator(def, substs, _)
-                if *drop_place == Place::Local(Local::new(1)) && !self.mir.upvar_decls.is_empty()
-            => {
-                substs.upvar_tys(def, self.tcx).enumerate()
+                if *drop_place == Place::Local(Local::new(1))
+                    && !self.mir.upvar_decls.is_empty() =>
+            {
+                substs
+                    .upvar_tys(def, self.tcx)
+                    .enumerate()
                     .for_each(|field| drop_field(self, field));
             }
             _ => {
@@ -900,7 +896,8 @@ fn access_place(
             }
         }
 
-        if self.access_place_error_reported
+        if self
+            .access_place_error_reported
             .contains(&(place_span.0.clone(), place_span.1))
         {
             debug!(
@@ -943,10 +940,7 @@ fn check_access_for_conflict(
     ) -> bool {
         debug!(
             "check_access_for_conflict(context={:?}, place_span={:?}, sd={:?}, rw={:?})",
-            context,
-            place_span,
-            sd,
-            rw,
+            context, place_span, sd, rw,
         );
 
         let mut error_reported = false;
@@ -963,8 +957,7 @@ fn check_access_for_conflict(
             (sd, place_span.0),
             &borrow_set,
             flow_state.borrows_in_scope(location),
-            |this, borrow_index, borrow|
-            match (rw, borrow.kind) {
+            |this, borrow_index, borrow| match (rw, borrow.kind) {
                 // Obviously an activation is compatible with its own
                 // reservation (or even prior activating uses of same
                 // borrow); so don't check if they interfere.
@@ -1001,12 +994,7 @@ fn check_access_for_conflict(
                         }
                         ReadKind::Borrow(bk) => {
                             error_reported = true;
-                            this.report_conflicting_borrow(
-                                context,
-                                place_span,
-                                bk,
-                                &borrow,
-                            )
+                            this.report_conflicting_borrow(context, place_span, bk, &borrow)
                         }
                     }
                     Control::Break
@@ -1038,12 +1026,7 @@ fn check_access_for_conflict(
                     match kind {
                         WriteKind::MutableBorrow(bk) => {
                             error_reported = true;
-                            this.report_conflicting_borrow(
-                                context,
-                                place_span,
-                                bk,
-                                &borrow,
-                            )
+                            this.report_conflicting_borrow(context, place_span, bk, &borrow)
                         }
                         WriteKind::StorageDeadOrDrop => {
                             error_reported = true;
@@ -1197,7 +1180,9 @@ fn consume_rvalue(
                 // moved into the closure and subsequently used by the closure,
                 // in order to populate our used_mut set.
                 if let AggregateKind::Closure(def_id, _) = &**aggregate_kind {
-                    let BorrowCheckResult { used_mut_upvars, .. } = self.tcx.mir_borrowck(*def_id);
+                    let BorrowCheckResult {
+                        used_mut_upvars, ..
+                    } = self.tcx.mir_borrowck(*def_id);
                     debug!("{:?} used_mut_upvars={:?}", def_id, used_mut_upvars);
                     for field in used_mut_upvars {
                         match operands[field.index()] {
@@ -1209,9 +1194,9 @@ fn consume_rvalue(
                                     self.used_mut_upvars.push(field);
                                 }
                             }
-                            Operand::Move(Place::Static(..)) |
-                            Operand::Copy(..) |
-                            Operand::Constant(..) => {}
+                            Operand::Move(Place::Static(..))
+                            | Operand::Copy(..)
+                            Operand::Constant(..) => {}
                         }
                     }
                 }
@@ -1292,7 +1277,8 @@ fn check_for_invalidation_at_exit(
             Place::Static(statik) => {
                 // Thread-locals might be dropped after the function exits, but
                 // "true" statics will never be.
-                let is_thread_local = self.tcx
+                let is_thread_local = self
+                    .tcx
                     .get_attrs(statik.def_id)
                     .iter()
                     .any(|attr| attr.check_name("thread_local"));
@@ -1688,8 +1674,7 @@ enum AccessKind {
             Reservation(WriteKind::MutableBorrow(borrow_kind @ BorrowKind::Unique))
             | Reservation(WriteKind::MutableBorrow(borrow_kind @ BorrowKind::Mut { .. }))
             | Write(WriteKind::MutableBorrow(borrow_kind @ BorrowKind::Unique))
-            | Write(WriteKind::MutableBorrow(borrow_kind @ BorrowKind::Mut { .. })) =>
-            {
+            | Write(WriteKind::MutableBorrow(borrow_kind @ BorrowKind::Mut { .. })) => {
                 let is_local_mutation_allowed = match borrow_kind {
                     BorrowKind::Unique => LocalMutationIsAllowed::Yes,
                     BorrowKind::Mut { .. } => is_local_mutation_allowed,
@@ -1759,28 +1744,33 @@ enum AccessKind {
 
         // `act` and `acted_on` are strings that let us abstract over
         // the verbs used in some diagnostic messages.
-        let act; let acted_on;
+        let act;
+        let acted_on;
 
         match error_access {
             AccessKind::Mutate => {
                 let item_msg = match the_place_err {
                     Place::Projection(box Projection {
                         base: _,
-                        elem: ProjectionElem::Deref }
-                    ) => match self.describe_place(place) {
-                        Some(description) =>
-                            format!("`{}` which is behind a `&` reference", description),
+                        elem: ProjectionElem::Deref,
+                    }) => match self.describe_place(place) {
+                        Some(description) => {
+                            format!("`{}` which is behind a `&` reference", description)
+                        }
                         None => format!("data in a `&` reference"),
                     },
                     _ => item_msg,
                 };
                 err = self.tcx.cannot_assign(span, &item_msg, Origin::Mir);
-                act = "assign"; acted_on = "written";
+                act = "assign";
+                acted_on = "written";
             }
             AccessKind::MutableBorrow => {
-                err = self.tcx
+                err = self
+                    .tcx
                     .cannot_borrow_path_as_mutable(span, &item_msg, Origin::Mir);
-                act = "borrow as mutable"; acted_on = "borrowed as mutable";
+                act = "borrow as mutable";
+                acted_on = "borrowed as mutable";
             }
         }
 
@@ -1795,23 +1785,27 @@ enum AccessKind {
                 let local_decl = &self.mir.local_decls[*local];
                 assert_eq!(local_decl.mutability, Mutability::Not);
 
-                err.span_label(span, format!("cannot {ACT}", ACT=act));
-                err.span_suggestion(local_decl.source_info.span,
-                                    "consider changing this to be mutable",
-                                    format!("mut {}", local_decl.name.unwrap()));
+                err.span_label(span, format!("cannot {ACT}", ACT = act));
+                err.span_suggestion(
+                    local_decl.source_info.span,
+                    "consider changing this to be mutable",
+                    format!("mut {}", local_decl.name.unwrap()),
+                );
             }
 
             // complete hack to approximate old AST-borrowck
             // diagnostic: if the span starts with a mutable borrow of
             // a local variable, then just suggest the user remove it.
-            Place::Local(_) if {
-                if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(span) {
-                    snippet.starts_with("&mut ")
-                } else {
-                    false
-                }
-            } => {
-                err.span_label(span, format!("cannot {ACT}", ACT=act));
+            Place::Local(_)
+                if {
+                    if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(span) {
+                        snippet.starts_with("&mut ")
+                    } else {
+                        false
+                    }
+                } =>
+            {
+                err.span_label(span, format!("cannot {ACT}", ACT = act));
                 err.span_label(span, "try removing `&mut` here");
             }
 
@@ -1820,29 +1814,40 @@ enum AccessKind {
             //
             // FIXME: can this case be generalized to work for an
             // arbitrary base for the projection?
-            Place::Projection(box Projection { base: Place::Local(local),
-                                               elem: ProjectionElem::Deref })
-                if self.mir.local_decls[*local].is_nonref_binding() =>
+            Place::Projection(box Projection {
+                base: Place::Local(local),
+                elem: ProjectionElem::Deref,
+            }) if self.mir.local_decls[*local].is_nonref_binding() =>
             {
                 let (err_help_span, suggested_code) =
                     find_place_to_suggest_ampmut(self.tcx, self.mir, *local);
-                err.span_suggestion(err_help_span,
-                                    "consider changing this to be a mutable reference",
-                                    suggested_code);
+                err.span_suggestion(
+                    err_help_span,
+                    "consider changing this to be a mutable reference",
+                    suggested_code,
+                );
 
                 let local_decl = &self.mir.local_decls[*local];
                 if let Some(name) = local_decl.name {
                     err.span_label(
-                        span, format!("`{NAME}` is a `&` reference, \
-                                       so the data it refers to cannot be {ACTED_ON}",
-                                      NAME=name, ACTED_ON=acted_on));
+                        span,
+                        format!(
+                            "`{NAME}` is a `&` reference, \
+                             so the data it refers to cannot be {ACTED_ON}",
+                            NAME = name,
+                            ACTED_ON = acted_on
+                        ),
+                    );
                 } else {
-                    err.span_label(span, format!("cannot {ACT} through `&`-reference", ACT=act));
+                    err.span_label(
+                        span,
+                        format!("cannot {ACT} through `&`-reference", ACT = act),
+                    );
                 }
             }
 
             _ => {
-                err.span_label(span, format!("cannot {ACT}", ACT=act));
+                err.span_label(span, format!("cannot {ACT}", ACT = act));
             }
         }
 
@@ -1864,10 +1869,11 @@ enum AccessKind {
         // for example, if the RHS is present and the Type is not, then the type is going to
         // be inferred *from* the RHS, which means we should highlight that (and suggest
         // that they borrow the RHS mutably).
-        fn find_place_to_suggest_ampmut<'cx, 'gcx, 'tcx>(tcx: TyCtxt<'cx, 'gcx, 'tcx>,
-                                                         mir: &Mir<'tcx>,
-                                                         local: Local) -> (Span, String)
-        {
+        fn find_place_to_suggest_ampmut<'cx, 'gcx, 'tcx>(
+            tcx: TyCtxt<'cx, 'gcx, 'tcx>,
+            mir: &Mir<'tcx>,
+            local: Local,
+        ) -> (Span, String) {
             // This implementation attempts to emulate AST-borrowck prioritization
             // by trying (3.), then (2.) and finally falling back on (1.).
             let locations = mir.find_assignments(local);
@@ -1889,7 +1895,9 @@ fn find_place_to_suggest_ampmut<'cx, 'gcx, 'tcx>(tcx: TyCtxt<'cx, 'gcx, 'tcx>,
                 // if this is a variable binding with an explicit type,
                 // try to highlight that for the suggestion.
                 Some(ClearCrossCrate::Set(mir::BindingForm::Var(mir::VarBindingForm {
-                    opt_ty_info: Some(ty_span), .. }))) => ty_span,
+                    opt_ty_info: Some(ty_span),
+                    ..
+                }))) => ty_span,
 
                 Some(ClearCrossCrate::Clear) => bug!("saw cleared local state"),
 
@@ -1908,7 +1916,7 @@ fn find_place_to_suggest_ampmut<'cx, 'gcx, 'tcx>(tcx: TyCtxt<'cx, 'gcx, 'tcx>,
     fn add_used_mut<'d>(
         &mut self,
         root_place: RootPlace<'d, 'tcx>,
-        flow_state: &Flows<'cx, 'gcx, 'tcx>
+        flow_state: &Flows<'cx, 'gcx, 'tcx>,
     ) {
         match root_place {
             RootPlace {
@@ -1956,29 +1964,32 @@ fn is_mutable<'d>(
                 let local = &self.mir.local_decls[local];
                 match local.mutability {
                     Mutability::Not => match is_local_mutation_allowed {
-                        LocalMutationIsAllowed::Yes => {
-                            Ok(RootPlace {
-                                place,
-                                is_local_mutation_allowed: LocalMutationIsAllowed::Yes
-                            })
-                        }
-                        LocalMutationIsAllowed::ExceptUpvars => {
-                            Ok(RootPlace {
-                                place,
-                                is_local_mutation_allowed: LocalMutationIsAllowed::ExceptUpvars
-                            })
-                        }
+                        LocalMutationIsAllowed::Yes => Ok(RootPlace {
+                            place,
+                            is_local_mutation_allowed: LocalMutationIsAllowed::Yes,
+                        }),
+                        LocalMutationIsAllowed::ExceptUpvars => Ok(RootPlace {
+                            place,
+                            is_local_mutation_allowed: LocalMutationIsAllowed::ExceptUpvars,
+                        }),
                         LocalMutationIsAllowed::No => Err(place),
                     },
-                    Mutability::Mut => Ok(RootPlace { place, is_local_mutation_allowed }),
+                    Mutability::Mut => Ok(RootPlace {
+                        place,
+                        is_local_mutation_allowed,
+                    }),
                 }
             }
-            Place::Static(ref static_) =>
+            Place::Static(ref static_) => {
                 if self.tcx.is_static(static_.def_id) != Some(hir::Mutability::MutMutable) {
                     Err(place)
                 } else {
-                    Ok(RootPlace { place, is_local_mutation_allowed })
-                },
+                    Ok(RootPlace {
+                        place,
+                        is_local_mutation_allowed,
+                    })
+                }
+            }
             Place::Projection(ref proj) => {
                 match proj.elem {
                     ProjectionElem::Deref => {
@@ -2016,7 +2027,10 @@ fn is_mutable<'d>(
                                     // `*mut` raw pointers are always mutable, regardless of
                                     // context. The users have to check by themselves.
                                     hir::MutMutable => {
-                                        return Ok(RootPlace { place, is_local_mutation_allowed });
+                                        return Ok(RootPlace {
+                                            place,
+                                            is_local_mutation_allowed,
+                                        });
                                     }
                                 }
                             }
@@ -2075,7 +2089,10 @@ fn is_mutable<'d>(
                                     // }
                                     // ```
                                     let _ = self.is_mutable(&proj.base, is_local_mutation_allowed)?;
-                                    Ok(RootPlace { place, is_local_mutation_allowed })
+                                    Ok(RootPlace {
+                                        place,
+                                        is_local_mutation_allowed,
+                                    })
                                 }
                             }
                         } else {
@@ -2095,7 +2112,8 @@ fn is_upvar_field_projection(&self, place: &Place<'tcx>) -> Option<Field> {
         match *place {
             Place::Projection(ref proj) => match proj.elem {
                 ProjectionElem::Field(field, _ty) => {
-                    let is_projection_from_ty_closure = proj.base
+                    let is_projection_from_ty_closure = proj
+                        .base
                         .ty(self.mir, self.tcx)
                         .to_ty(self.tcx)
                         .is_closure();
@@ -2197,4 +2215,3 @@ fn new(self, loc: Location) -> Context {
         }
     }
 }
-
diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs
new file mode 100644 (file)
index 0000000..dbe19bc
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use rustc::mir::visit::{PlaceContext, Visitor};
+use rustc::mir::{Local, Location, Place};
+
+use rustc_data_structures::fx::FxHashSet;
+
+use borrow_check::MirBorrowckCtxt;
+use util::collect_writes::is_place_assignment;
+
+impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
+    /// Walks the MIR looking for assignments to a set of locals, as part of the unused mutable
+    /// local variables lint, to update the context's `used_mut` in a single walk.
+    crate fn gather_used_muts(&mut self, locals: FxHashSet<Local>) {
+        let mut visitor = GatherUsedMutsVisitor {
+            needles: locals,
+            mbcx: self,
+        };
+        visitor.visit_mir(visitor.mbcx.mir);
+    }
+}
+
+/// MIR visitor gathering the assignments to a set of locals, in a single walk.
+/// 'visit = the duration of the MIR walk
+struct GatherUsedMutsVisitor<'visit, 'cx: 'visit, 'gcx: 'tcx, 'tcx: 'cx> {
+    needles: FxHashSet<Local>,
+    mbcx: &'visit mut MirBorrowckCtxt<'cx, 'gcx, 'tcx>,
+}
+
+impl<'visit, 'cx, 'gcx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'gcx, 'tcx> {
+    fn visit_local(
+        &mut self,
+        local: &Local,
+        place_context: PlaceContext<'tcx>,
+        location: Location,
+    ) {
+        if !self.needles.contains(local) {
+            return;
+        }
+
+        if is_place_assignment(&place_context) {
+            // Propagate the Local assigned at this Location as a used mutable local variable
+            for moi in &self.mbcx.move_data.loc_map[location] {
+                let mpi = &self.mbcx.move_data.moves[*moi].path;
+                let path = &self.mbcx.move_data.move_paths[*mpi];
+                debug!(
+                    "assignment of {:?} to {:?}, adding {:?} to used mutable set",
+                    path.place, local, path.place
+                );
+                if let Place::Local(user_local) = path.place {
+                    self.mbcx.used_mut.insert(user_local);
+                }
+            }
+        }
+    }
+}
index ee0a087a1dd0ae9860199e80afa58d8fc4cac970..b9d6486d9174a9117ca38c11d7aed88c4567fb17 100644 (file)
@@ -540,12 +540,12 @@ pub fn new_source_scope(&mut self,
     // ==============
     /// Finds the breakable scope for a given label. This is used for
     /// resolving `break` and `continue`.
-    pub fn find_breakable_scope(&mut self,
+    pub fn find_breakable_scope(&self,
                            span: Span,
                            label: region::Scope)
-                           -> &mut BreakableScope<'tcx> {
+                           -> &BreakableScope<'tcx> {
         // find the loop-scope with the correct id
-        self.breakable_scopes.iter_mut()
+        self.breakable_scopes.iter()
             .rev()
             .filter(|breakable_scope| breakable_scope.region_scope == label)
             .next()
index f23e10ae5d2d80071fc65fef0780a993eb0d6864..9c6c35a340e2fd7d1f1dc8591385baad7dd20fbb 100644 (file)
@@ -543,7 +543,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                 Err(err) => bug!("invalid loop id for break: {}", err)
             }
         }
-        hir::ExprAgain(dest) => {
+        hir::ExprContinue(dest) => {
             match dest.target_id {
                 Ok(loop_id) => ExprKind::Continue {
                     label: region::Scope::Node(cx.tcx.hir.node_to_hir_id(loop_id).local_id),
index a7b2e205d006df27c72eabc76e9fa03944abea89..41024e60202739161e46548566c4764385f8ac24 100644 (file)
@@ -25,6 +25,7 @@
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 
 use rustc::mir::Field;
+use rustc::mir::interpret::ConstValue;
 use rustc::util::common::ErrorReported;
 
 use syntax_pos::{Span, DUMMY_SP};
@@ -932,16 +933,20 @@ fn slice_pat_covered_by_constructor<'tcx>(
     suffix: &[Pattern<'tcx>]
 ) -> Result<bool, ErrorReported> {
     let data: &[u8] = match *ctor {
-        ConstantValue(const_val @ &ty::Const { val: ConstVal::Value(..), .. }) => {
-            if let Some(ptr) = const_val.to_ptr() {
-                let is_array_ptr = const_val.ty
+        ConstantValue(&ty::Const { val: ConstVal::Value(const_val), ty }) => {
+            let val = match const_val {
+                ConstValue::ByRef(..) => bug!("unexpected ConstValue::ByRef"),
+                ConstValue::Scalar(val) | ConstValue::ScalarPair(val, _) => val,
+            };
+            if let Ok(ptr) = val.to_ptr() {
+                let is_array_ptr = ty
                     .builtin_deref(true)
                     .and_then(|t| t.ty.builtin_index())
                     .map_or(false, |t| t == tcx.types.u8);
                 assert!(is_array_ptr);
                 tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id).bytes.as_ref()
             } else {
-                bug!()
+                bug!("unexpected non-ptr ConstantValue")
             }
         }
         _ => bug!()
index 7cef8a75aa6baf90d881b038c6a06ca43a55baba..4ac896d84ff6e97f5ca68a22173f0eee4fa10fc4 100644 (file)
@@ -23,7 +23,7 @@
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::subst::Substs;
 use rustc::lint;
-use rustc_errors::DiagnosticBuilder;
+use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc::util::common::ErrorReported;
 
 use rustc::hir::def::*;
@@ -295,7 +295,7 @@ fn check_irrefutable(&self, pat: &'tcx Pat, origin: &str) {
             );
             let label_msg = match pat.node {
                 PatKind::Path(hir::QPath::Resolved(None, ref path))
-                        if path.segments.len() == 1 && path.segments[0].parameters.is_none() => {
+                        if path.segments.len() == 1 && path.segments[0].args.is_none() => {
                     format!("interpreted as a {} pattern, not new variable", path.def.kind_name())
                 }
                 _ => format!("pattern `{}` not covered", pattern_string),
@@ -328,10 +328,12 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchVisitor, pat: &Pat) {
                         "pattern binding `{}` is named the same as one \
                          of the variants of the type `{}`",
                         name.node, ty_path);
-                    help!(err,
-                        "if you meant to match on a variant, \
-                        consider making the path in the pattern qualified: `{}::{}`",
-                        ty_path, name.node);
+                    err.span_suggestion_with_applicability(
+                        p.span,
+                        "to match on the variant, qualify the path",
+                        format!("{}::{}", ty_path, name.node),
+                        Applicability::MachineApplicable
+                    );
                     err.emit();
                 }
             }
@@ -369,43 +371,56 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
                 NotUseful => {
                     match source {
                         hir::MatchSource::IfLetDesugar { .. } => {
-                            if printed_if_let_err {
-                                // we already printed an irrefutable if-let pattern error.
-                                // We don't want two, that's just confusing.
+                            if cx.tcx.features().irrefutable_let_patterns {
+                                cx.tcx.lint_node(
+                                    lint::builtin::IRREFUTABLE_LET_PATTERNS,
+                                    hir_pat.id, pat.span,
+                                    "irrefutable if-let pattern");
                             } else {
-                                // find the first arm pattern so we can use its span
-                                let &(ref first_arm_pats, _) = &arms[0];
-                                let first_pat = &first_arm_pats[0];
-                                let span = first_pat.0.span;
-                                struct_span_err!(cx.tcx.sess, span, E0162,
-                                                "irrefutable if-let pattern")
-                                    .span_label(span, "irrefutable pattern")
-                                    .emit();
-                                printed_if_let_err = true;
+                                if printed_if_let_err {
+                                    // we already printed an irrefutable if-let pattern error.
+                                    // We don't want two, that's just confusing.
+                                } else {
+                                    // find the first arm pattern so we can use its span
+                                    let &(ref first_arm_pats, _) = &arms[0];
+                                    let first_pat = &first_arm_pats[0];
+                                    let span = first_pat.0.span;
+                                    struct_span_err!(cx.tcx.sess, span, E0162,
+                                                    "irrefutable if-let pattern")
+                                        .span_label(span, "irrefutable pattern")
+                                        .emit();
+                                    printed_if_let_err = true;
+                                }
                             }
                         },
 
                         hir::MatchSource::WhileLetDesugar => {
-                            // find the first arm pattern so we can use its span
-                            let &(ref first_arm_pats, _) = &arms[0];
-                            let first_pat = &first_arm_pats[0];
-                            let span = first_pat.0.span;
-
                             // check which arm we're on.
                             match arm_index {
                                 // The arm with the user-specified pattern.
                                 0 => {
                                     cx.tcx.lint_node(
-                                            lint::builtin::UNREACHABLE_PATTERNS,
+                                        lint::builtin::UNREACHABLE_PATTERNS,
                                         hir_pat.id, pat.span,
                                         "unreachable pattern");
                                 },
                                 // The arm with the wildcard pattern.
                                 1 => {
-                                    struct_span_err!(cx.tcx.sess, span, E0165,
-                                                     "irrefutable while-let pattern")
-                                        .span_label(span, "irrefutable pattern")
-                                        .emit();
+                                    if cx.tcx.features().irrefutable_let_patterns {
+                                        cx.tcx.lint_node(
+                                            lint::builtin::IRREFUTABLE_LET_PATTERNS,
+                                            hir_pat.id, pat.span,
+                                            "irrefutable while-let pattern");
+                                    } else {
+                                        // find the first arm pattern so we can use its span
+                                        let &(ref first_arm_pats, _) = &arms[0];
+                                        let first_pat = &first_arm_pats[0];
+                                        let span = first_pat.0.span;
+                                        struct_span_err!(cx.tcx.sess, span, E0165,
+                                                         "irrefutable while-let pattern")
+                                            .span_label(span, "irrefutable pattern")
+                                            .emit();
+                                    }
                                 },
                                 _ => bug!(),
                             }
index 7dae79530c488d6a8abba1111479e831729fe9c4..9b92a8b5e7861edff98293cf2e23de07beee3eb3 100644 (file)
@@ -416,7 +416,6 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
             }
 
             PatKind::Slice(ref prefix, ref slice, ref suffix) => {
-                let ty = self.tables.node_id_to_type(pat.hir_id);
                 match ty.sty {
                     ty::TyRef(_, ty, _) =>
                         PatternKind::Deref {
@@ -427,11 +426,12 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
                                     pat.span, ty, prefix, slice, suffix))
                             },
                         },
-
                     ty::TySlice(..) |
                     ty::TyArray(..) =>
                         self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix),
-
+                    ty::TyError => { // Avoid ICE
+                        return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) };
+                    }
                     ref sty =>
                         span_bug!(
                             pat.span,
@@ -441,7 +441,6 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
             }
 
             PatKind::Tuple(ref subpatterns, ddpos) => {
-                let ty = self.tables.node_id_to_type(pat.hir_id);
                 match ty.sty {
                     ty::TyTuple(ref tys) => {
                         let subpatterns =
@@ -455,7 +454,9 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
 
                         PatternKind::Leaf { subpatterns: subpatterns }
                     }
-
+                    ty::TyError => { // Avoid ICE (#50577)
+                        return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) };
+                    }
                     ref sty => span_bug!(pat.span, "unexpected type for tuple pattern: {:?}", sty),
                 }
             }
@@ -464,6 +465,9 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
                 let var_ty = self.tables.node_id_to_type(pat.hir_id);
                 let region = match var_ty.sty {
                     ty::TyRef(r, _, _) => Some(r),
+                    ty::TyError => { // Avoid ICE
+                        return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) };
+                    }
                     _ => None,
                 };
                 let bm = *self.tables.pat_binding_modes().get(pat.hir_id)
@@ -505,7 +509,12 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
                 let def = self.tables.qpath_def(qpath, pat.hir_id);
                 let adt_def = match ty.sty {
                     ty::TyAdt(adt_def, _) => adt_def,
-                    _ => span_bug!(pat.span, "tuple struct pattern not applied to an ADT"),
+                    ty::TyError => { // Avoid ICE (#50585)
+                        return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) };
+                    }
+                    _ => span_bug!(pat.span,
+                                   "tuple struct pattern not applied to an ADT {:?}",
+                                   ty.sty),
                 };
                 let variant_def = adt_def.variant_of_def(def);
 
@@ -637,6 +646,9 @@ fn lower_variant_or_leaf(
                     let substs = match ty.sty {
                         ty::TyAdt(_, substs) |
                         ty::TyFnDef(_, substs) => substs,
+                        ty::TyError => {  // Avoid ICE (#50585)
+                            return PatternKind::Wild;
+                        }
                         _ => bug!("inappropriate type for def: {:?}", ty.sty),
                     };
                     PatternKind::Variant {
index 96aeb969d89f96eb20f367b49609748498373db2..ef69cb574e07e6b70571899b23b92ba1f72dfc16 100644 (file)
@@ -1099,14 +1099,12 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                  item: &'tcx hir::Item,
                                                  output: &mut Vec<MonoItem<'tcx>>) {
     match item.node {
-        hir::ItemImpl(_,
-                      _,
-                      _,
-                      ref generics,
-                      ..,
-                      ref impl_item_refs) => {
-            if generics.is_type_parameterized() {
-                return
+        hir::ItemImpl(_, _, _, ref generics, .., ref impl_item_refs) => {
+            for param in &generics.params {
+                match param.kind {
+                    hir::GenericParamKind::Lifetime { .. } => {}
+                    hir::GenericParamKind::Type { .. } => return,
+                }
             }
 
             let impl_def_id = tcx.hir.local_def_id(item.id);
index 5f8f9acae838515a45f81ffdef12ef3579a130aa..00e064fbb4717ce541a61a629ab05e021bfd8367 100644 (file)
@@ -380,10 +380,10 @@ fn is_enclosed(tcx: TyCtxt,
         if used_unsafe.contains(&parent_id) {
             Some(("block".to_string(), parent_id))
         } else if let Some(hir::map::NodeItem(&hir::Item {
-            node: hir::ItemFn(_, fn_unsafety, _, _, _, _),
+            node: hir::ItemFn(_, header, _, _),
             ..
         })) = tcx.hir.find(parent_id) {
-            match fn_unsafety {
+            match header.unsafety {
                 hir::Unsafety::Unsafe => Some(("fn".to_string(), parent_id)),
                 hir::Unsafety::Normal => None,
             }
index d01b90ad2628e02eb683b2396a6cc08972e51a54..be87365bdbb5d98bb370ffca66e6071ff667aae6 100644 (file)
@@ -8,15 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use rustc::ty::{self, TyCtxt};
 use rustc::session::config::BorrowckMode;
+use rustc::ty::{self, TyCtxt};
 use rustc_errors::{DiagnosticBuilder, DiagnosticId};
 use syntax_pos::{MultiSpan, Span};
 
 use std::fmt;
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub enum Origin { Ast, Mir }
+pub enum Origin {
+    Ast,
+    Mir,
+}
 
 impl fmt::Display for Origin {
     fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
@@ -53,94 +56,130 @@ pub fn should_emit_errors(self, mode: BorrowckMode) -> bool {
 }
 
 pub trait BorrowckErrors<'cx>: Sized + Copy {
-    fn struct_span_err_with_code<S: Into<MultiSpan>>(self,
-                                                     sp: S,
-                                                     msg: &str,
-                                                     code: DiagnosticId)
-                                                     -> DiagnosticBuilder<'cx>;
+    fn struct_span_err_with_code<S: Into<MultiSpan>>(
+        self,
+        sp: S,
+        msg: &str,
+        code: DiagnosticId,
+    ) -> DiagnosticBuilder<'cx>;
 
-    fn struct_span_err<S: Into<MultiSpan>>(self,
-                                           sp: S,
-                                           msg: &str)
-                                           -> DiagnosticBuilder<'cx>;
+    fn struct_span_err<S: Into<MultiSpan>>(self, sp: S, msg: &str) -> DiagnosticBuilder<'cx>;
 
     /// Cancels the given error if we shouldn't emit errors for a given
     /// origin in the current mode.
     ///
     /// Always make sure that the error gets passed through this function
     /// before you return it.
-    fn cancel_if_wrong_origin(self,
-                              diag: DiagnosticBuilder<'cx>,
-                              o: Origin)
-                              -> DiagnosticBuilder<'cx>;
-
-    fn cannot_move_when_borrowed(self, span: Span, desc: &str, o: Origin)
-                                 -> DiagnosticBuilder<'cx>
-    {
-        let err = struct_span_err!(self, span, E0505,
-                                   "cannot move out of `{}` because it is borrowed{OGN}",
-                                   desc, OGN=o);
+    fn cancel_if_wrong_origin(
+        self,
+        diag: DiagnosticBuilder<'cx>,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx>;
+
+    fn cannot_move_when_borrowed(
+        self,
+        span: Span,
+        desc: &str,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let err = struct_span_err!(
+            self,
+            span,
+            E0505,
+            "cannot move out of `{}` because it is borrowed{OGN}",
+            desc,
+            OGN = o
+        );
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_use_when_mutably_borrowed(self,
-                                        span: Span,
-                                        desc: &str,
-                                        borrow_span: Span,
-                                        borrow_desc: &str,
-                                        o: Origin)
-                                        -> DiagnosticBuilder<'cx>
-    {
-        let mut err = struct_span_err!(self, span, E0503,
-                         "cannot use `{}` because it was mutably borrowed{OGN}",
-                         desc, OGN=o);
-
-        err.span_label(borrow_span, format!("borrow of `{}` occurs here", borrow_desc));
+    fn cannot_use_when_mutably_borrowed(
+        self,
+        span: Span,
+        desc: &str,
+        borrow_span: Span,
+        borrow_desc: &str,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let mut err = struct_span_err!(
+            self,
+            span,
+            E0503,
+            "cannot use `{}` because it was mutably borrowed{OGN}",
+            desc,
+            OGN = o
+        );
+
+        err.span_label(
+            borrow_span,
+            format!("borrow of `{}` occurs here", borrow_desc),
+        );
         err.span_label(span, format!("use of borrowed `{}`", borrow_desc));
 
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_act_on_uninitialized_variable(self,
-                                            span: Span,
-                                            verb: &str,
-                                            desc: &str,
-                                            o: Origin)
-                                            -> DiagnosticBuilder<'cx>
-    {
-        let err = struct_span_err!(self, span, E0381,
-                                   "{} of possibly uninitialized variable: `{}`{OGN}",
-                                   verb, desc, OGN=o);
+    fn cannot_act_on_uninitialized_variable(
+        self,
+        span: Span,
+        verb: &str,
+        desc: &str,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let err = struct_span_err!(
+            self,
+            span,
+            E0381,
+            "{} of possibly uninitialized variable: `{}`{OGN}",
+            verb,
+            desc,
+            OGN = o
+        );
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_mutably_borrow_multiply(self,
-                                      new_loan_span: Span,
-                                      desc: &str,
-                                      opt_via: &str,
-                                      old_loan_span: Span,
-                                      old_opt_via: &str,
-                                      old_load_end_span: Option<Span>,
-                                      o: Origin)
-                                      -> DiagnosticBuilder<'cx>
-    {
-        let mut err = struct_span_err!(self, new_loan_span, E0499,
-                         "cannot borrow `{}`{} as mutable more than once at a time{OGN}",
-                         desc, opt_via, OGN=o);
+    fn cannot_mutably_borrow_multiply(
+        self,
+        new_loan_span: Span,
+        desc: &str,
+        opt_via: &str,
+        old_loan_span: Span,
+        old_opt_via: &str,
+        old_load_end_span: Option<Span>,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let mut err = struct_span_err!(
+            self,
+            new_loan_span,
+            E0499,
+            "cannot borrow `{}`{} as mutable more than once at a time{OGN}",
+            desc,
+            opt_via,
+            OGN = o
+        );
         if old_loan_span == new_loan_span {
             // Both borrows are happening in the same place
             // Meaning the borrow is occurring in a loop
-            err.span_label(new_loan_span,
-                           format!("mutable borrow starts here in previous \
-                                    iteration of loop{}", opt_via));
+            err.span_label(
+                new_loan_span,
+                format!(
+                    "mutable borrow starts here in previous \
+                     iteration of loop{}",
+                    opt_via
+                ),
+            );
             if let Some(old_load_end_span) = old_load_end_span {
                 err.span_label(old_load_end_span, "mutable borrow ends here");
             }
         } else {
-            err.span_label(old_loan_span,
-                           format!("first mutable borrow occurs here{}", old_opt_via));
-            err.span_label(new_loan_span,
-                           format!("second mutable borrow occurs here{}", opt_via));
+            err.span_label(
+                old_loan_span,
+                format!("first mutable borrow occurs here{}", old_opt_via),
+            );
+            err.span_label(
+                new_loan_span,
+                format!("second mutable borrow occurs here{}", opt_via),
+            );
             if let Some(old_load_end_span) = old_load_end_span {
                 err.span_label(old_load_end_span, "first borrow ends here");
             }
@@ -148,166 +187,222 @@ fn cannot_mutably_borrow_multiply(self,
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_uniquely_borrow_by_two_closures(self,
-                                              new_loan_span: Span,
-                                              desc: &str,
-                                              old_loan_span: Span,
-                                              old_load_end_span: Option<Span>,
-                                              o: Origin)
-                                              -> DiagnosticBuilder<'cx>
-    {
-        let mut err = struct_span_err!(self, new_loan_span, E0524,
-                         "two closures require unique access to `{}` at the same time{OGN}",
-                         desc, OGN=o);
-        err.span_label(
-            old_loan_span,
-            "first closure is constructed here");
-        err.span_label(
+    fn cannot_uniquely_borrow_by_two_closures(
+        self,
+        new_loan_span: Span,
+        desc: &str,
+        old_loan_span: Span,
+        old_load_end_span: Option<Span>,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let mut err = struct_span_err!(
+            self,
             new_loan_span,
-            "second closure is constructed here");
+            E0524,
+            "two closures require unique access to `{}` at the same time{OGN}",
+            desc,
+            OGN = o
+        );
+        err.span_label(old_loan_span, "first closure is constructed here");
+        err.span_label(new_loan_span, "second closure is constructed here");
         if let Some(old_load_end_span) = old_load_end_span {
-            err.span_label(
-                old_load_end_span,
-                "borrow from first closure ends here");
+            err.span_label(old_load_end_span, "borrow from first closure ends here");
         }
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_uniquely_borrow_by_one_closure(self,
-                                             new_loan_span: Span,
-                                             desc_new: &str,
-                                             opt_via: &str,
-                                             old_loan_span: Span,
-                                             noun_old: &str,
-                                             old_opt_via: &str,
-                                             previous_end_span: Option<Span>,
-                                             o: Origin)
-                                             -> DiagnosticBuilder<'cx>
-    {
-        let mut err = struct_span_err!(self, new_loan_span, E0500,
-                         "closure requires unique access to `{}` but {} is already borrowed{}{OGN}",
-                         desc_new, noun_old, old_opt_via, OGN=o);
-        err.span_label(new_loan_span,
-                       format!("closure construction occurs here{}", opt_via));
-        err.span_label(old_loan_span,
-                       format!("borrow occurs here{}", old_opt_via));
+    fn cannot_uniquely_borrow_by_one_closure(
+        self,
+        new_loan_span: Span,
+        desc_new: &str,
+        opt_via: &str,
+        old_loan_span: Span,
+        noun_old: &str,
+        old_opt_via: &str,
+        previous_end_span: Option<Span>,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let mut err = struct_span_err!(
+            self,
+            new_loan_span,
+            E0500,
+            "closure requires unique access to `{}` but {} is already borrowed{}{OGN}",
+            desc_new,
+            noun_old,
+            old_opt_via,
+            OGN = o
+        );
+        err.span_label(
+            new_loan_span,
+            format!("closure construction occurs here{}", opt_via),
+        );
+        err.span_label(old_loan_span, format!("borrow occurs here{}", old_opt_via));
         if let Some(previous_end_span) = previous_end_span {
             err.span_label(previous_end_span, "borrow ends here");
         }
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_reborrow_already_uniquely_borrowed(self,
-                                                 new_loan_span: Span,
-                                                 desc_new: &str,
-                                                 opt_via: &str,
-                                                 kind_new: &str,
-                                                 old_loan_span: Span,
-                                                 old_opt_via: &str,
-                                                 previous_end_span: Option<Span>,
-                                                 o: Origin)
-                                                 -> DiagnosticBuilder<'cx>
-    {
-        let mut err = struct_span_err!(self, new_loan_span, E0501,
-                         "cannot borrow `{}`{} as {} because previous closure \
-                          requires unique access{OGN}",
-                         desc_new, opt_via, kind_new, OGN=o);
-        err.span_label(new_loan_span,
-                       format!("borrow occurs here{}", opt_via));
-        err.span_label(old_loan_span,
-                       format!("closure construction occurs here{}", old_opt_via));
+    fn cannot_reborrow_already_uniquely_borrowed(
+        self,
+        new_loan_span: Span,
+        desc_new: &str,
+        opt_via: &str,
+        kind_new: &str,
+        old_loan_span: Span,
+        old_opt_via: &str,
+        previous_end_span: Option<Span>,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let mut err = struct_span_err!(
+            self,
+            new_loan_span,
+            E0501,
+            "cannot borrow `{}`{} as {} because previous closure \
+             requires unique access{OGN}",
+            desc_new,
+            opt_via,
+            kind_new,
+            OGN = o
+        );
+        err.span_label(new_loan_span, format!("borrow occurs here{}", opt_via));
+        err.span_label(
+            old_loan_span,
+            format!("closure construction occurs here{}", old_opt_via),
+        );
         if let Some(previous_end_span) = previous_end_span {
             err.span_label(previous_end_span, "borrow from closure ends here");
         }
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_reborrow_already_borrowed(self,
-                                        span: Span,
-                                        desc_new: &str,
-                                        msg_new: &str,
-                                        kind_new: &str,
-                                        old_span: Span,
-                                        noun_old: &str,
-                                        kind_old: &str,
-                                        msg_old: &str,
-                                        old_load_end_span: Option<Span>,
-                                        o: Origin)
-                                        -> DiagnosticBuilder<'cx>
-    {
-        let mut err = struct_span_err!(self, span, E0502,
-                         "cannot borrow `{}`{} as {} because {} is also borrowed as {}{}{OGN}",
-                         desc_new, msg_new, kind_new, noun_old, kind_old, msg_old, OGN=o);
+    fn cannot_reborrow_already_borrowed(
+        self,
+        span: Span,
+        desc_new: &str,
+        msg_new: &str,
+        kind_new: &str,
+        old_span: Span,
+        noun_old: &str,
+        kind_old: &str,
+        msg_old: &str,
+        old_load_end_span: Option<Span>,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let mut err = struct_span_err!(
+            self,
+            span,
+            E0502,
+            "cannot borrow `{}`{} as {} because {} is also borrowed as {}{}{OGN}",
+            desc_new,
+            msg_new,
+            kind_new,
+            noun_old,
+            kind_old,
+            msg_old,
+            OGN = o
+        );
         err.span_label(span, format!("{} borrow occurs here{}", kind_new, msg_new));
-        err.span_label(old_span, format!("{} borrow occurs here{}", kind_old, msg_old));
+        err.span_label(
+            old_span,
+            format!("{} borrow occurs here{}", kind_old, msg_old),
+        );
         if let Some(old_load_end_span) = old_load_end_span {
             err.span_label(old_load_end_span, format!("{} borrow ends here", kind_old));
         }
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_assign_to_borrowed(self, span: Span, borrow_span: Span, desc: &str, o: Origin)
-                                 -> DiagnosticBuilder<'cx>
-    {
-        let mut err = struct_span_err!(self, span, E0506,
-                         "cannot assign to `{}` because it is borrowed{OGN}",
-                         desc, OGN=o);
+    fn cannot_assign_to_borrowed(
+        self,
+        span: Span,
+        borrow_span: Span,
+        desc: &str,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let mut err = struct_span_err!(
+            self,
+            span,
+            E0506,
+            "cannot assign to `{}` because it is borrowed{OGN}",
+            desc,
+            OGN = o
+        );
 
         err.span_label(borrow_span, format!("borrow of `{}` occurs here", desc));
-        err.span_label(span, format!("assignment to borrowed `{}` occurs here", desc));
+        err.span_label(
+            span,
+            format!("assignment to borrowed `{}` occurs here", desc),
+        );
 
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_move_into_closure(self, span: Span, desc: &str, o: Origin)
-                                -> DiagnosticBuilder<'cx>
-    {
-        let err = struct_span_err!(self, span, E0504,
-                                   "cannot move `{}` into closure because it is borrowed{OGN}",
-                                   desc, OGN=o);
+    fn cannot_move_into_closure(self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx> {
+        let err = struct_span_err!(
+            self,
+            span,
+            E0504,
+            "cannot move `{}` into closure because it is borrowed{OGN}",
+            desc,
+            OGN = o
+        );
 
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_reassign_immutable(self, span: Span, desc: &str, is_arg: bool, o: Origin)
-                                 -> DiagnosticBuilder<'cx>
-    {
+    fn cannot_reassign_immutable(
+        self,
+        span: Span,
+        desc: &str,
+        is_arg: bool,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
         let msg = if is_arg {
             "to immutable argument"
         } else {
             "twice to immutable variable"
         };
-        let err = struct_span_err!(self, span, E0384,
-                                   "cannot assign {} `{}`{OGN}",
-                                   msg, desc, OGN=o);
+        let err = struct_span_err!(
+            self,
+            span,
+            E0384,
+            "cannot assign {} `{}`{OGN}",
+            msg,
+            desc,
+            OGN = o
+        );
 
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_assign(self, span: Span, desc: &str, o: Origin)
-                     -> DiagnosticBuilder<'cx>
-    {
-        let err = struct_span_err!(self, span, E0594,
-                                  "cannot assign to {}{OGN}",
-                                  desc, OGN=o);
+    fn cannot_assign(self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx> {
+        let err = struct_span_err!(self, span, E0594, "cannot assign to {}{OGN}", desc, OGN = o);
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_assign_static(self, span: Span, desc: &str, o: Origin)
-                            -> DiagnosticBuilder<'cx>
-    {
+    fn cannot_assign_static(self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx> {
         self.cannot_assign(span, &format!("immutable static item `{}`", desc), o)
     }
 
-    fn cannot_move_out_of(self, move_from_span: Span, move_from_desc: &str, o: Origin)
-                          -> DiagnosticBuilder<'cx>
-    {
-        let mut err = struct_span_err!(self, move_from_span, E0507,
-                                       "cannot move out of {}{OGN}",
-                                       move_from_desc, OGN=o);
+    fn cannot_move_out_of(
+        self,
+        move_from_span: Span,
+        move_from_desc: &str,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let mut err = struct_span_err!(
+            self,
+            move_from_span,
+            E0507,
+            "cannot move out of {}{OGN}",
+            move_from_desc,
+            OGN = o
+        );
         err.span_label(
             move_from_span,
-            format!("cannot move out of {}", move_from_desc));
+            format!("cannot move out of {}", move_from_desc),
+        );
 
         self.cancel_if_wrong_origin(err, o)
     }
@@ -315,210 +410,274 @@ fn cannot_move_out_of(self, move_from_span: Span, move_from_desc: &str, o: Origi
     /// Signal an error due to an attempt to move out of the interior
     /// of an array or slice. `is_index` is None when error origin
     /// didn't capture whether there was an indexing operation or not.
-    fn cannot_move_out_of_interior_noncopy(self,
-                                           move_from_span: Span,
-                                           ty: ty::Ty,
-                                           is_index: Option<bool>,
-                                           o: Origin)
-                                           -> DiagnosticBuilder<'cx>
-    {
+    fn cannot_move_out_of_interior_noncopy(
+        self,
+        move_from_span: Span,
+        ty: ty::Ty,
+        is_index: Option<bool>,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
         let type_name = match (&ty.sty, is_index) {
-            (&ty::TyArray(_, _), Some(true)) |
-            (&ty::TyArray(_, _), None) => "array",
-            (&ty::TySlice(_),    _) => "slice",
+            (&ty::TyArray(_, _), Some(true)) | (&ty::TyArray(_, _), None) => "array",
+            (&ty::TySlice(_), _) => "slice",
             _ => span_bug!(move_from_span, "this path should not cause illegal move"),
         };
-        let mut err = struct_span_err!(self, move_from_span, E0508,
-                                       "cannot move out of type `{}`, \
-                                        a non-copy {}{OGN}",
-                                       ty, type_name, OGN=o);
+        let mut err = struct_span_err!(
+            self,
+            move_from_span,
+            E0508,
+            "cannot move out of type `{}`, \
+             a non-copy {}{OGN}",
+            ty,
+            type_name,
+            OGN = o
+        );
         err.span_label(move_from_span, "cannot move out of here");
 
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_move_out_of_interior_of_drop(self,
-                                           move_from_span: Span,
-                                           container_ty: ty::Ty,
-                                           o: Origin)
-                                           -> DiagnosticBuilder<'cx>
-    {
-        let mut err = struct_span_err!(self, move_from_span, E0509,
-                                       "cannot move out of type `{}`, \
-                                        which implements the `Drop` trait{OGN}",
-                                       container_ty, OGN=o);
+    fn cannot_move_out_of_interior_of_drop(
+        self,
+        move_from_span: Span,
+        container_ty: ty::Ty,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let mut err = struct_span_err!(
+            self,
+            move_from_span,
+            E0509,
+            "cannot move out of type `{}`, \
+             which implements the `Drop` trait{OGN}",
+            container_ty,
+            OGN = o
+        );
         err.span_label(move_from_span, "cannot move out of here");
 
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_act_on_moved_value(self,
-                                 use_span: Span,
-                                 verb: &str,
-                                 optional_adverb_for_moved: &str,
-                                 moved_path: &str,
-                                 o: Origin)
-                                 -> DiagnosticBuilder<'cx>
-    {
-        let err = struct_span_err!(self, use_span, E0382,
-                                   "{} of {}moved value: `{}`{OGN}",
-                                   verb, optional_adverb_for_moved, moved_path, OGN=o);
+    fn cannot_act_on_moved_value(
+        self,
+        use_span: Span,
+        verb: &str,
+        optional_adverb_for_moved: &str,
+        moved_path: Option<String>,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let moved_path = moved_path
+            .map(|mp| format!(": `{}`", mp))
+            .unwrap_or("".to_owned());
+
+        let err = struct_span_err!(
+            self,
+            use_span,
+            E0382,
+            "{} of {}moved value{}{OGN}",
+            verb,
+            optional_adverb_for_moved,
+            moved_path,
+            OGN = o
+        );
 
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_partially_reinit_an_uninit_struct(self,
-                                                span: Span,
-                                                uninit_path: &str,
-                                                o: Origin)
-                                                -> DiagnosticBuilder<'cx>
-    {
-        let err = struct_span_err!(self,
-                                   span,
-                                   E0383,
-                                   "partial reinitialization of uninitialized structure `{}`{OGN}",
-                                   uninit_path, OGN=o);
+    fn cannot_partially_reinit_an_uninit_struct(
+        self,
+        span: Span,
+        uninit_path: &str,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let err = struct_span_err!(
+            self,
+            span,
+            E0383,
+            "partial reinitialization of uninitialized structure `{}`{OGN}",
+            uninit_path,
+            OGN = o
+        );
 
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn closure_cannot_assign_to_borrowed(self,
-                                         span: Span,
-                                         descr: &str,
-                                         o: Origin)
-                                         -> DiagnosticBuilder<'cx>
-    {
-        let err = struct_span_err!(self, span, E0595, "closure cannot assign to {}{OGN}",
-                                   descr, OGN=o);
+    fn closure_cannot_assign_to_borrowed(
+        self,
+        span: Span,
+        descr: &str,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let err = struct_span_err!(
+            self,
+            span,
+            E0595,
+            "closure cannot assign to {}{OGN}",
+            descr,
+            OGN = o
+        );
 
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_borrow_path_as_mutable(self,
-                                     span: Span,
-                                     path: &str,
-                                     o: Origin)
-                                     -> DiagnosticBuilder<'cx>
-    {
-        let err = struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{OGN}",
-                                   path, OGN=o);
+    fn cannot_borrow_path_as_mutable(
+        self,
+        span: Span,
+        path: &str,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let err = struct_span_err!(
+            self,
+            span,
+            E0596,
+            "cannot borrow {} as mutable{OGN}",
+            path,
+            OGN = o
+        );
 
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_borrow_across_generator_yield(self,
-                                            span: Span,
-                                            yield_span: Span,
-                                            o: Origin)
-                                            -> DiagnosticBuilder<'cx>
-    {
-        let mut err = struct_span_err!(self,
-                                       span,
-                                       E0626,
-                                       "borrow may still be in use when generator yields{OGN}",
-                                       OGN=o);
+    fn cannot_borrow_across_generator_yield(
+        self,
+        span: Span,
+        yield_span: Span,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let mut err = struct_span_err!(
+            self,
+            span,
+            E0626,
+            "borrow may still be in use when generator yields{OGN}",
+            OGN = o
+        );
         err.span_label(yield_span, "possible yield occurs here");
 
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn path_does_not_live_long_enough(self,
-                                      span: Span,
-                                      path: &str,
-                                      o: Origin)
-                                      -> DiagnosticBuilder<'cx>
-    {
-        let err = struct_span_err!(self, span, E0597, "{} does not live long enough{OGN}",
-                                   path, OGN=o);
+    fn path_does_not_live_long_enough(
+        self,
+        span: Span,
+        path: &str,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let err = struct_span_err!(
+            self,
+            span,
+            E0597,
+            "{} does not live long enough{OGN}",
+            path,
+            OGN = o
+        );
 
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn lifetime_too_short_for_reborrow(self,
-                                       span: Span,
-                                       path: &str,
-                                       o: Origin)
-                                       -> DiagnosticBuilder<'cx>
-    {
-        let err = struct_span_err!(self, span, E0598,
-                                   "lifetime of {} is too short to guarantee \
-                                    its contents can be safely reborrowed{OGN}",
-                                   path, OGN=o);
+    fn lifetime_too_short_for_reborrow(
+        self,
+        span: Span,
+        path: &str,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let err = struct_span_err!(
+            self,
+            span,
+            E0598,
+            "lifetime of {} is too short to guarantee \
+             its contents can be safely reborrowed{OGN}",
+            path,
+            OGN = o
+        );
 
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_act_on_capture_in_sharable_fn(self,
-                                            span: Span,
-                                            bad_thing: &str,
-                                            help: (Span, &str),
-                                            o: Origin)
-                                            -> DiagnosticBuilder<'cx>
-    {
+    fn cannot_act_on_capture_in_sharable_fn(
+        self,
+        span: Span,
+        bad_thing: &str,
+        help: (Span, &str),
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
         let (help_span, help_msg) = help;
-        let mut err = struct_span_err!(self, span, E0387,
-                                       "{} in a captured outer variable in an `Fn` closure{OGN}",
-                                       bad_thing, OGN=o);
+        let mut err = struct_span_err!(
+            self,
+            span,
+            E0387,
+            "{} in a captured outer variable in an `Fn` closure{OGN}",
+            bad_thing,
+            OGN = o
+        );
         err.span_help(help_span, help_msg);
 
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_assign_into_immutable_reference(self,
-                                              span: Span,
-                                              bad_thing: &str,
-                                              o: Origin)
-                                              -> DiagnosticBuilder<'cx>
-    {
-        let mut err = struct_span_err!(self, span, E0389, "{} in a `&` reference{OGN}",
-                                       bad_thing, OGN=o);
+    fn cannot_assign_into_immutable_reference(
+        self,
+        span: Span,
+        bad_thing: &str,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let mut err = struct_span_err!(
+            self,
+            span,
+            E0389,
+            "{} in a `&` reference{OGN}",
+            bad_thing,
+            OGN = o
+        );
         err.span_label(span, "assignment into an immutable reference");
 
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_capture_in_long_lived_closure(self,
-                                            closure_span: Span,
-                                            borrowed_path: &str,
-                                            capture_span: Span,
-                                            o: Origin)
-                                            -> DiagnosticBuilder<'cx>
-    {
-        let mut err = struct_span_err!(self, closure_span, E0373,
-                                       "closure may outlive the current function, \
-                                        but it borrows {}, \
-                                        which is owned by the current function{OGN}",
-                                       borrowed_path, OGN=o);
+    fn cannot_capture_in_long_lived_closure(
+        self,
+        closure_span: Span,
+        borrowed_path: &str,
+        capture_span: Span,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
+        let mut err = struct_span_err!(
+            self,
+            closure_span,
+            E0373,
+            "closure may outlive the current function, \
+             but it borrows {}, \
+             which is owned by the current function{OGN}",
+            borrowed_path,
+            OGN = o
+        );
         err.span_label(capture_span, format!("{} is borrowed here", borrowed_path))
-            .span_label(closure_span, format!("may outlive borrowed value {}", borrowed_path));
+            .span_label(
+                closure_span,
+                format!("may outlive borrowed value {}", borrowed_path),
+            );
 
         self.cancel_if_wrong_origin(err, o)
     }
 }
 
 impl<'cx, 'gcx, 'tcx> BorrowckErrors<'cx> for TyCtxt<'cx, 'gcx, 'tcx> {
-    fn struct_span_err_with_code<S: Into<MultiSpan>>(self,
-                                                     sp: S,
-                                                     msg: &str,
-                                                     code: DiagnosticId)
-                                                     -> DiagnosticBuilder<'cx>
-    {
+    fn struct_span_err_with_code<S: Into<MultiSpan>>(
+        self,
+        sp: S,
+        msg: &str,
+        code: DiagnosticId,
+    ) -> DiagnosticBuilder<'cx> {
         self.sess.struct_span_err_with_code(sp, msg, code)
     }
 
-    fn struct_span_err<S: Into<MultiSpan>>(self,
-                                           sp: S,
-                                           msg: &str)
-                                           -> DiagnosticBuilder<'cx>
-    {
+    fn struct_span_err<S: Into<MultiSpan>>(self, sp: S, msg: &str) -> DiagnosticBuilder<'cx> {
         self.sess.struct_span_err(sp, msg)
     }
 
-    fn cancel_if_wrong_origin(self,
-                              mut diag: DiagnosticBuilder<'cx>,
-                              o: Origin)
-                              -> DiagnosticBuilder<'cx>
-    {
+    fn cancel_if_wrong_origin(
+        self,
+        mut diag: DiagnosticBuilder<'cx>,
+        o: Origin,
+    ) -> DiagnosticBuilder<'cx> {
         if !o.should_emit_errors(self.borrowck_mode()) {
             self.sess.diagnostic().cancel(&mut diag);
         }
index f04f9233447c3d83761a34836fa913182de3aa0c..23f753f8569bb780170cb0118e6c61a453106f48 100644 (file)
@@ -43,25 +43,24 @@ fn visit_local(&mut self,
             return;
         }
 
-        match place_context {
-            PlaceContext::Store | PlaceContext::Call => {
-                self.locations.push(location);
-            }
-            PlaceContext::AsmOutput |
-            PlaceContext::Drop |
-            PlaceContext::Inspect |
-            PlaceContext::Borrow { .. } |
-            PlaceContext::Projection(..) |
-            PlaceContext::Copy |
-            PlaceContext::Move |
-            PlaceContext::StorageLive |
-            PlaceContext::StorageDead |
-            PlaceContext::Validate => {
-                // TO-DO
-                // self.super_local(local)
-            }
+        if is_place_assignment(&place_context) {
+            self.locations.push(location);
         }
     }
-    // TO-DO
-    // fn super_local()
+}
+
+/// Returns true if this place context represents an assignment statement
+crate fn is_place_assignment(place_context: &PlaceContext) -> bool {
+    match *place_context {
+        PlaceContext::Store | PlaceContext::Call | PlaceContext::AsmOutput => true,
+        PlaceContext::Drop
+        | PlaceContext::Inspect
+        | PlaceContext::Borrow { .. }
+        | PlaceContext::Projection(..)
+        | PlaceContext::Copy
+        | PlaceContext::Move
+        | PlaceContext::StorageLive
+        | PlaceContext::StorageDead
+        | PlaceContext::Validate => false,
+    }
 }
index 39e0a5392580b26349dea251d897dac2f6bf6220..25187032fb47365bbb393100237b54893e0cc1e5 100644 (file)
@@ -87,6 +87,13 @@ fn check_decl_no_pat<ReportFn: Fn(Span, bool)>(&self, decl: &FnDecl, report_err:
         }
     }
 
+    fn check_trait_fn_not_async(&self, span: Span, asyncness: IsAsync) {
+        if asyncness.is_async() {
+            struct_span_err!(self.session, span, E0706,
+                             "trait fns cannot be declared `async`").emit()
+        }
+    }
+
     fn check_trait_fn_not_const(&self, constness: Spanned<Constness>) {
         match constness.node {
             Constness::Const => {
@@ -99,9 +106,9 @@ fn check_trait_fn_not_const(&self, constness: Spanned<Constness>) {
         }
     }
 
-    fn no_questions_in_bounds(&self, bounds: &TyParamBounds, where_: &str, is_trait: bool) {
+    fn no_questions_in_bounds(&self, bounds: &GenericBounds, where_: &str, is_trait: bool) {
         for bound in bounds {
-            if let TraitTyParamBound(ref poly, TraitBoundModifier::Maybe) = *bound {
+            if let GenericBound::Trait(ref poly, TraitBoundModifier::Maybe) = *bound {
                 let mut err = self.err_handler().struct_span_err(poly.span,
                                     &format!("`?Trait` is not permitted in {}", where_));
                 if is_trait {
@@ -139,29 +146,22 @@ fn check_expr_within_pat(&self, expr: &Expr, allow_paths: bool) {
     }
 
     fn check_late_bound_lifetime_defs(&self, params: &Vec<GenericParam>) {
-        // Check: Only lifetime parameters
-        let non_lifetime_param_spans : Vec<_> = params.iter()
-            .filter_map(|param| match *param {
-                GenericParam::Lifetime(_) => None,
-                GenericParam::Type(ref t) => Some(t.ident.span),
-            }).collect();
-        if !non_lifetime_param_spans.is_empty() {
-            self.err_handler().span_err(non_lifetime_param_spans,
-                "only lifetime parameters can be used in this context");
-        }
-
-        // Check: No bounds on lifetime parameters
-        for param in params.iter() {
-            match *param {
-                GenericParam::Lifetime(ref l) => {
-                    if !l.bounds.is_empty() {
-                        let spans: Vec<_> = l.bounds.iter().map(|b| b.ident.span).collect();
-                        self.err_handler().span_err(spans,
-                            "lifetime bounds cannot be used in this context");
+        // Check only lifetime parameters are present and that the lifetime
+        // parameters that are present have no bounds.
+        let non_lt_param_spans: Vec<_> = params.iter().filter_map(|param| match param.kind {
+                GenericParamKind::Lifetime { .. } => {
+                    if !param.bounds.is_empty() {
+                        let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
+                        self.err_handler()
+                            .span_err(spans, "lifetime bounds cannot be used in this context");
                     }
+                    None
                 }
-                GenericParam::Type(_) => {}
-            }
+                _ => Some(param.ident.span),
+            }).collect();
+        if !non_lt_param_spans.is_empty() {
+            self.err_handler().span_err(non_lt_param_spans,
+                "only lifetime parameters can be used in this context");
         }
     }
 }
@@ -197,7 +197,7 @@ fn visit_ty(&mut self, ty: &'a Ty) {
             TyKind::TraitObject(ref bounds, ..) => {
                 let mut any_lifetime_bounds = false;
                 for bound in bounds {
-                    if let RegionTyParamBound(ref lifetime) = *bound {
+                    if let GenericBound::Outlives(ref lifetime) = *bound {
                         if any_lifetime_bounds {
                             span_err!(self.session, lifetime.ident.span, E0226,
                                       "only a single explicit lifetime bound is permitted");
@@ -210,7 +210,7 @@ fn visit_ty(&mut self, ty: &'a Ty) {
             }
             TyKind::ImplTrait(ref bounds) => {
                 if !bounds.iter()
-                          .any(|b| if let TraitTyParamBound(..) = *b { true } else { false }) {
+                          .any(|b| if let GenericBound::Trait(..) = *b { true } else { false }) {
                     self.err_handler().span_err(ty.span, "at least one trait must be specified");
                 }
             }
@@ -230,9 +230,9 @@ fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) {
         // }
         // foo!(bar::baz<T>);
         use_tree.prefix.segments.iter().find(|segment| {
-            segment.parameters.is_some()
+            segment.args.is_some()
         }).map(|segment| {
-            self.err_handler().span_err(segment.parameters.as_ref().unwrap().span(),
+            self.err_handler().span_err(segment.args.as_ref().unwrap().span(),
                                         "generic arguments in import path");
         });
 
@@ -264,7 +264,8 @@ fn visit_item(&mut self, item: &'a Item) {
                 for impl_item in impl_items {
                     self.invalid_visibility(&impl_item.vis, None);
                     if let ImplItemKind::Method(ref sig, _) = impl_item.node {
-                        self.check_trait_fn_not_const(sig.constness);
+                        self.check_trait_fn_not_const(sig.header.constness);
+                        self.check_trait_fn_not_async(impl_item.span, sig.header.asyncness);
                     }
                 }
             }
@@ -300,7 +301,7 @@ fn visit_item(&mut self, item: &'a Item) {
             ItemKind::Trait(is_auto, _, ref generics, ref bounds, ref trait_items) => {
                 if is_auto == IsAuto::Yes {
                     // Auto traits cannot have generics, super traits nor contain items.
-                    if generics.is_parameterized() {
+                    if !generics.params.is_empty() {
                         struct_span_err!(self.session, item.span, E0567,
                                         "auto traits cannot have generic parameters").emit();
                     }
@@ -316,7 +317,8 @@ fn visit_item(&mut self, item: &'a Item) {
                 self.no_questions_in_bounds(bounds, "supertraits", true);
                 for trait_item in trait_items {
                     if let TraitItemKind::Method(ref sig, ref block) = trait_item.node {
-                        self.check_trait_fn_not_const(sig.constness);
+                        self.check_trait_fn_not_async(trait_item.span, sig.header.asyncness);
+                        self.check_trait_fn_not_const(sig.header.constness);
                         if block.is_none() {
                             self.check_decl_no_pat(&sig.decl, |span, mut_ident| {
                                 if mut_ident {
@@ -335,22 +337,19 @@ fn visit_item(&mut self, item: &'a Item) {
             }
             ItemKind::TraitAlias(Generics { ref params, .. }, ..) => {
                 for param in params {
-                    if let GenericParam::Type(TyParam {
-                        ident,
-                        ref bounds,
-                        ref default,
-                        ..
-                    }) = *param
-                    {
-                        if !bounds.is_empty() {
-                            self.err_handler().span_err(ident.span,
-                                                        "type parameters on the left side of a \
-                                                         trait alias cannot be bounded");
-                        }
-                        if !default.is_none() {
-                            self.err_handler().span_err(ident.span,
-                                                        "type parameters on the left side of a \
-                                                         trait alias cannot have defaults");
+                    match param.kind {
+                        GenericParamKind::Lifetime { .. } => {}
+                        GenericParamKind::Type { ref default, .. } => {
+                            if !param.bounds.is_empty() {
+                                self.err_handler()
+                                    .span_err(param.ident.span, "type parameters on the left \
+                                        side of a trait alias cannot be bounded");
+                            }
+                            if !default.is_none() {
+                                self.err_handler()
+                                    .span_err(param.ident.span, "type parameters on the left \
+                                        side of a trait alias cannot have defaults");
+                            }
                         }
                     }
                 }
@@ -398,8 +397,8 @@ fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
     fn visit_vis(&mut self, vis: &'a Visibility) {
         match vis.node {
             VisibilityKind::Restricted { ref path, .. } => {
-                path.segments.iter().find(|segment| segment.parameters.is_some()).map(|segment| {
-                    self.err_handler().span_err(segment.parameters.as_ref().unwrap().span(),
+                path.segments.iter().find(|segment| segment.args.is_some()).map(|segment| {
+                    self.err_handler().span_err(segment.args.as_ref().unwrap().span(),
                                                 "generic arguments in visibility path");
                 });
             }
@@ -409,41 +408,40 @@ fn visit_vis(&mut self, vis: &'a Visibility) {
         visit::walk_vis(self, vis)
     }
 
-    fn visit_generics(&mut self, g: &'a Generics) {
+    fn visit_generics(&mut self, generics: &'a Generics) {
         let mut seen_non_lifetime_param = false;
         let mut seen_default = None;
-        for param in &g.params {
-            match (param, seen_non_lifetime_param) {
-                (&GenericParam::Lifetime(ref ld), true) => {
+        for param in &generics.params {
+            match (&param.kind, seen_non_lifetime_param) {
+                (GenericParamKind::Lifetime { .. }, true) => {
                     self.err_handler()
-                        .span_err(ld.lifetime.ident.span, "lifetime parameters must be leading");
+                        .span_err(param.ident.span, "lifetime parameters must be leading");
                 },
-                (&GenericParam::Lifetime(_), false) => {}
-                _ => {
+                (GenericParamKind::Lifetime { .. }, false) => {}
+                (GenericParamKind::Type { ref default, .. }, _) => {
                     seen_non_lifetime_param = true;
+                    if default.is_some() {
+                        seen_default = Some(param.ident.span);
+                    } else if let Some(span) = seen_default {
+                        self.err_handler()
+                            .span_err(span, "type parameters with a default must be trailing");
+                        break;
+                    }
                 }
             }
-
-            if let GenericParam::Type(ref ty_param @ TyParam { default: Some(_), .. }) = *param {
-                seen_default = Some(ty_param.ident.span);
-            } else if let Some(span) = seen_default {
-                self.err_handler()
-                    .span_err(span, "type parameters with a default must be trailing");
-                break
-            }
         }
-        for predicate in &g.where_clause.predicates {
+        for predicate in &generics.where_clause.predicates {
             if let WherePredicate::EqPredicate(ref predicate) = *predicate {
                 self.err_handler().span_err(predicate.span, "equality constraints are not yet \
                                                              supported in where clauses (#20041)");
             }
         }
-        visit::walk_generics(self, g)
+        visit::walk_generics(self, generics)
     }
 
     fn visit_generic_param(&mut self, param: &'a GenericParam) {
-        if let GenericParam::Lifetime(ref ld) = *param {
-            self.check_lifetime(ld.lifetime.ident);
+        if let GenericParamKind::Lifetime { .. } = param.kind {
+            self.check_lifetime(param.ident);
         }
         visit::walk_generic_param(self, param);
     }
@@ -521,23 +519,24 @@ fn visit_ty(&mut self, t: &'a Ty) {
             visit::walk_ty(self, t);
         }
     }
-    fn visit_path_parameters(&mut self, _: Span, path_parameters: &'a PathParameters) {
-        match *path_parameters {
-            PathParameters::AngleBracketed(ref params) => {
-                for type_ in &params.types {
-                    self.visit_ty(type_);
-                }
-                for type_binding in &params.bindings {
+    fn visit_generic_args(&mut self, _: Span, generic_args: &'a GenericArgs) {
+        match *generic_args {
+            GenericArgs::AngleBracketed(ref data) => {
+                data.args.iter().for_each(|arg| match arg {
+                    GenericArg::Type(ty) => self.visit_ty(ty),
+                    _ => {}
+                });
+                for type_binding in &data.bindings {
                     // Type bindings such as `Item=impl Debug` in `Iterator<Item=Debug>`
                     // are allowed to contain nested `impl Trait`.
                     self.with_impl_trait(None, |this| visit::walk_ty(this, &type_binding.ty));
                 }
             }
-            PathParameters::Parenthesized(ref params) => {
-                for type_ in &params.inputs {
+            GenericArgs::Parenthesized(ref data) => {
+                for type_ in &data.inputs {
                     self.visit_ty(type_);
                 }
-                if let Some(ref type_) = params.output {
+                if let Some(ref type_) = data.output {
                     // `-> Foo` syntax is essentially an associated type binding,
                     // so it is also allowed to contain nested `impl Trait`.
                     self.with_impl_trait(None, |this| visit::walk_ty(this, type_));
@@ -590,7 +589,7 @@ fn visit_ty(&mut self, t: &'a Ty) {
                 //
                 // To implement this, we disallow `impl Trait` from `qself`
                 // (for cases like `<impl Trait>::Foo>`)
-                // but we allow `impl Trait` in `PathParameters`
+                // but we allow `impl Trait` in `GenericArgs`
                 // iff there are no more PathSegments.
                 if let Some(ref qself) = *qself {
                     // `impl Trait` in `qself` is always illegal
index d031694d85308a1d1cbc97f9aaec3f21a2540acf..f1ec3371c3b9ab0400bd0b3a60daecff1497dcd3 100644 (file)
@@ -310,4 +310,5 @@ fn foo() {}
     E0666, // nested `impl Trait` is illegal
     E0667, // `impl Trait` in projections
     E0696, // `continue` pointing to a labeled block
+    E0706, // `async fn` in trait
 }
index ba0be974b2771997292c2df43b29614aeaac7ef0..e7b2869dfe61eaaea68c0f03df8350a07f7c9c5e 100644 (file)
@@ -203,9 +203,9 @@ fn visit_impl_item(&mut self, ii: &'v hir::ImplItem) {
         hir_visit::walk_impl_item(self, ii)
     }
 
-    fn visit_ty_param_bound(&mut self, bounds: &'v hir::TyParamBound) {
-        self.record("TyParamBound", Id::None, bounds);
-        hir_visit::walk_ty_param_bound(self, bounds)
+    fn visit_param_bound(&mut self, bounds: &'v hir::GenericBound) {
+        self.record("GenericBound", Id::None, bounds);
+        hir_visit::walk_param_bound(self, bounds)
     }
 
     fn visit_struct_field(&mut self, s: &'v hir::StructField) {
@@ -322,9 +322,9 @@ fn visit_impl_item(&mut self, ii: &'v ast::ImplItem) {
         ast_visit::walk_impl_item(self, ii)
     }
 
-    fn visit_ty_param_bound(&mut self, bounds: &'v ast::TyParamBound) {
-        self.record("TyParamBound", Id::None, bounds);
-        ast_visit::walk_ty_param_bound(self, bounds)
+    fn visit_param_bound(&mut self, bounds: &'v ast::GenericBound) {
+        self.record("GenericBound", Id::None, bounds);
+        ast_visit::walk_param_bound(self, bounds)
     }
 
     fn visit_struct_field(&mut self, s: &'v ast::StructField) {
index 4719f00b4d25929068af9789f80ee8693dfcbf02..c99f1e9da439f04ce9b3133814123ed977511745 100644 (file)
@@ -148,7 +148,7 @@ fn visit_expr(&mut self, e: &'hir hir::Expr) {
 
                 self.require_break_cx("break", e.span);
             }
-            hir::ExprAgain(label) => {
+            hir::ExprContinue(label) => {
                 self.require_label_in_labeled_block(e.span, &label, "continue");
 
                 match label.target_id {
index 51b2988023b4a08b0dfecbd932ee69ff291ede52..e9d03daa7ea06b82dd3d5e5794f4f9883204edfc 100644 (file)
@@ -469,7 +469,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
 
         // More control flow (also not very meaningful).
         hir::ExprBreak(..) |
-        hir::ExprAgain(_) |
+        hir::ExprContinue(_) |
         hir::ExprRet(_) |
 
         // Generator expressions
index 291092015b57f06c208538d7d52b66c22985680b..de087049267b1f1ed82a4db643497692355a3061 100644 (file)
@@ -22,7 +22,7 @@
 extern crate syntax_pos;
 extern crate rustc_data_structures;
 
-use rustc::hir::{self, PatKind};
+use rustc::hir::{self, GenericParamKind, PatKind};
 use rustc::hir::def::Def;
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId};
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
@@ -1037,9 +1037,8 @@ fn trait_is_public(&self, trait_id: ast::NodeId) -> bool {
         self.access_levels.is_public(trait_id)
     }
 
-    fn check_ty_param_bound(&mut self,
-                            ty_param_bound: &hir::TyParamBound) {
-        if let hir::TraitTyParamBound(ref trait_ref, _) = *ty_param_bound {
+    fn check_generic_bound(&mut self, bound: &hir::GenericBound) {
+        if let hir::GenericBound::Trait(ref trait_ref, _) = *bound {
             if self.path_is_private_type(&trait_ref.trait_ref.path) {
                 self.old_error_set.insert(trait_ref.trait_ref.ref_id);
             }
@@ -1101,7 +1100,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                 }
 
                 for bound in bounds.iter() {
-                    self.check_ty_param_bound(bound)
+                    self.check_generic_bound(bound)
                 }
             }
 
@@ -1268,16 +1267,19 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
     }
 
     fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
-        for ty_param in generics.ty_params() {
-            for bound in ty_param.bounds.iter() {
-                self.check_ty_param_bound(bound)
+        generics.params.iter().for_each(|param| match param.kind {
+            GenericParamKind::Lifetime { .. } => {}
+            GenericParamKind::Type { .. } => {
+                for bound in &param.bounds {
+                    self.check_generic_bound(bound);
+                }
             }
-        }
+        });
         for predicate in &generics.where_clause.predicates {
             match predicate {
                 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
                     for bound in bound_pred.bounds.iter() {
-                        self.check_ty_param_bound(bound)
+                        self.check_generic_bound(bound)
                     }
                 }
                 &hir::WherePredicate::RegionPredicate(_) => {}
index a2b2096ccaa47aa01cf39bfa5587ea91556cfce3..2052918747b39301f1f14364c7d244b77a7eb00c 100644 (file)
@@ -45,7 +45,7 @@
 use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap};
 
 use syntax::codemap::CodeMap;
-use syntax::ext::hygiene::{Mark, MarkKind, SyntaxContext};
+use syntax::ext::hygiene::{Mark, Transparency, SyntaxContext};
 use syntax::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy};
 use syntax::ext::base::SyntaxExtension;
 use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
@@ -55,8 +55,8 @@
 
 use syntax::visit::{self, FnKind, Visitor};
 use syntax::attr;
-use syntax::ast::{Arm, BindingMode, Block, Crate, Expr, ExprKind};
-use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, GenericParam, Generics};
+use syntax::ast::{Arm, IsAsync, BindingMode, Block, Crate, Expr, ExprKind};
+use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, GenericParamKind, Generics};
 use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
 use syntax::ast::{Label, Local, Mutability, Pat, PatKind, Path};
 use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind};
@@ -746,15 +746,17 @@ fn visit_fn(&mut self,
                 function_kind: FnKind<'tcx>,
                 declaration: &'tcx FnDecl,
                 _: Span,
-                node_id: NodeId) {
-        let rib_kind = match function_kind {
-            FnKind::ItemFn(..) => {
-                ItemRibKind
-            }
-            FnKind::Method(_, _, _, _) => {
-                TraitOrImplItemRibKind
-            }
-            FnKind::Closure(_) => ClosureRibKind(node_id),
+                node_id: NodeId)
+    {
+        let (rib_kind, asyncness) = match function_kind {
+            FnKind::ItemFn(_, ref header, ..) =>
+                (ItemRibKind, header.asyncness),
+            FnKind::Method(_, ref sig, _, _) =>
+                (TraitOrImplItemRibKind, sig.header.asyncness),
+            FnKind::Closure(_) =>
+                // Async closures aren't resolved through `visit_fn`-- they're
+                // processed separately
+                (ClosureRibKind(node_id), IsAsync::NotAsync),
         };
 
         // Create a value rib for the function.
@@ -774,7 +776,13 @@ fn visit_fn(&mut self,
         }
         visit::walk_fn_ret_ty(self, &declaration.output);
 
-        // Resolve the function body.
+        // Resolve the function body, potentially inside the body of an async closure
+        if let IsAsync::Async(async_closure_id) = asyncness {
+            let rib_kind = ClosureRibKind(async_closure_id);
+            self.ribs[ValueNS].push(Rib::new(rib_kind));
+            self.label_ribs.push(Rib::new(rib_kind));
+        }
+
         match function_kind {
             FnKind::ItemFn(.., body) |
             FnKind::Method(.., body) => {
@@ -785,6 +793,12 @@ fn visit_fn(&mut self,
             }
         };
 
+        // Leave the body of the async closure
+        if asyncness.is_async() {
+            self.label_ribs.pop();
+            self.ribs[ValueNS].pop();
+        }
+
         debug!("(resolving function) leaving function");
 
         self.label_ribs.pop();
@@ -797,31 +811,41 @@ fn visit_generics(&mut self, generics: &'tcx Generics) {
         // put all the parameters on the ban list and then remove
         // them one by one as they are processed and become available.
         let mut default_ban_rib = Rib::new(ForwardTyParamBanRibKind);
+        let mut found_default = false;
         default_ban_rib.bindings.extend(generics.params.iter()
-            .filter_map(|p| if let GenericParam::Type(ref tp) = *p { Some(tp) } else { None })
-            .skip_while(|p| p.default.is_none())
-            .map(|p| (Ident::with_empty_ctxt(p.ident.name), Def::Err)));
+            .filter_map(|param| match param.kind {
+                GenericParamKind::Lifetime { .. } => None,
+                GenericParamKind::Type { ref default, .. } => {
+                    if found_default || default.is_some() {
+                        found_default = true;
+                        return Some((Ident::with_empty_ctxt(param.ident.name), Def::Err));
+                    }
+                    None
+                }
+            }));
 
         for param in &generics.params {
-            match *param {
-                GenericParam::Lifetime(_) => self.visit_generic_param(param),
-                GenericParam::Type(ref ty_param) => {
-                    for bound in &ty_param.bounds {
-                        self.visit_ty_param_bound(bound);
+            match param.kind {
+                GenericParamKind::Lifetime { .. } => self.visit_generic_param(param),
+                GenericParamKind::Type { ref default, .. } => {
+                    for bound in &param.bounds {
+                        self.visit_param_bound(bound);
                     }
 
-                    if let Some(ref ty) = ty_param.default {
+                    if let Some(ref ty) = default {
                         self.ribs[TypeNS].push(default_ban_rib);
                         self.visit_ty(ty);
                         default_ban_rib = self.ribs[TypeNS].pop().unwrap();
                     }
 
                     // Allow all following defaults to refer to this type parameter.
-                    default_ban_rib.bindings.remove(&Ident::with_empty_ctxt(ty_param.ident.name));
+                    default_ban_rib.bindings.remove(&Ident::with_empty_ctxt(param.ident.name));
                 }
             }
         }
-        for p in &generics.where_clause.predicates { self.visit_where_predicate(p); }
+        for p in &generics.where_clause.predicates {
+            self.visit_where_predicate(p);
+        }
     }
 }
 
@@ -1465,14 +1489,34 @@ fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool) {
                                  |resolver, span, error| resolve_error(resolver, span, error))
     }
 
-    fn resolve_str_path(&mut self, span: Span, crate_root: Option<&str>,
-                        components: &[&str], is_value: bool) -> hir::Path {
+    fn resolve_str_path(
+        &mut self,
+        span: Span,
+        crate_root: Option<&str>,
+        components: &[&str],
+        args: Option<P<hir::GenericArgs>>,
+        is_value: bool
+    ) -> hir::Path {
+        let mut segments = iter::once(keywords::CrateRoot.name())
+            .chain(
+                crate_root.into_iter()
+                    .chain(components.iter().cloned())
+                    .map(Symbol::intern)
+            ).map(hir::PathSegment::from_name).collect::<Vec<_>>();
+
+        if let Some(args) = args {
+            let name = segments.last().unwrap().name;
+            *segments.last_mut().unwrap() = hir::PathSegment {
+                name,
+                args: Some(args),
+                infer_types: true,
+            };
+        }
+
         let mut path = hir::Path {
             span,
             def: Def::Err,
-            segments: iter::once(keywords::CrateRoot.name()).chain({
-                crate_root.into_iter().chain(components.iter().cloned()).map(Symbol::intern)
-            }).map(hir::PathSegment::from_name).collect(),
+            segments: segments.into(),
         };
 
         self.resolve_hir_path(&mut path, is_value);
@@ -1944,7 +1988,7 @@ fn resolve_crate_root(&mut self, mut ctxt: SyntaxContext, legacy: bool) -> Modul
             // When resolving `$crate` from a `macro_rules!` invoked in a `macro`,
             // we don't want to pretend that the `macro_rules!` definition is in the `macro`
             // as described in `SyntaxContext::apply_mark`, so we ignore prepended modern marks.
-            ctxt.marks().into_iter().find(|&mark| mark.kind() != MarkKind::Modern)
+            ctxt.marks().into_iter().find(|&mark| mark.transparency() != Transparency::Opaque)
         } else {
             ctxt = ctxt.modern();
             ctxt.adjust(Mark::root())
@@ -2048,9 +2092,9 @@ fn resolve_item(&mut self, item: &Item) {
             ItemKind::Ty(_, ref generics) |
             ItemKind::Struct(_, ref generics) |
             ItemKind::Union(_, ref generics) |
-            ItemKind::Fn(.., ref generics, _) => {
+            ItemKind::Fn(_, _, ref generics, _) => {
                 self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind),
-                                             |this| visit::walk_item(this, item));
+                                         |this| visit::walk_item(this, item));
             }
 
             ItemKind::Impl(.., ref generics, ref opt_trait_ref, ref self_type, ref impl_items) =>
@@ -2066,7 +2110,7 @@ fn resolve_item(&mut self, item: &Item) {
                     let local_def_id = this.definitions.local_def_id(item.id);
                     this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
                         this.visit_generics(generics);
-                        walk_list!(this, visit_ty_param_bound, bounds);
+                        walk_list!(this, visit_param_bound, bounds);
 
                         for trait_item in trait_items {
                             this.check_proc_macro_attrs(&trait_item.attrs);
@@ -2109,7 +2153,7 @@ fn resolve_item(&mut self, item: &Item) {
                     let local_def_id = this.definitions.local_def_id(item.id);
                     this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
                         this.visit_generics(generics);
-                        walk_list!(this, visit_ty_param_bound, bounds);
+                        walk_list!(this, visit_param_bound, bounds);
                     });
                 });
             }
@@ -2197,10 +2241,11 @@ fn with_type_parameter_rib<'b, F>(&'b mut self, type_parameters: TypeParameters<
             HasTypeParameters(generics, rib_kind) => {
                 let mut function_type_rib = Rib::new(rib_kind);
                 let mut seen_bindings = FxHashMap();
-                for param in &generics.params {
-                    if let GenericParam::Type(ref type_parameter) = *param {
-                        let ident = type_parameter.ident.modern();
-                        debug!("with_type_parameter_rib: {}", type_parameter.id);
+                generics.params.iter().for_each(|param| match param.kind {
+                    GenericParamKind::Lifetime { .. } => {}
+                    GenericParamKind::Type { .. } => {
+                        let ident = param.ident.modern();
+                        debug!("with_type_parameter_rib: {}", param.id);
 
                         if seen_bindings.contains_key(&ident) {
                             let span = seen_bindings.get(&ident).unwrap();
@@ -2208,17 +2253,16 @@ fn with_type_parameter_rib<'b, F>(&'b mut self, type_parameters: TypeParameters<
                                 ident.name,
                                 span,
                             );
-                            resolve_error(self, type_parameter.ident.span, err);
+                            resolve_error(self, param.ident.span, err);
                         }
-                        seen_bindings.entry(ident).or_insert(type_parameter.ident.span);
+                        seen_bindings.entry(ident).or_insert(param.ident.span);
 
-                        // plain insert (no renaming)
-                        let def_id = self.definitions.local_def_id(type_parameter.id);
-                        let def = Def::TyParam(def_id);
+                    // Plain insert (no renaming).
+                    let def = Def::TyParam(self.definitions.local_def_id(param.id));
                         function_type_rib.bindings.insert(ident, def);
-                        self.record_def(type_parameter.id, PathResolution::new(def));
+                        self.record_def(param.id, PathResolution::new(def));
                     }
-                }
+                });
                 self.ribs[TypeNS].push(function_type_rib);
             }
 
@@ -2364,7 +2408,7 @@ fn resolve_implementation(&mut self,
                                                 visit::walk_impl_item(this, impl_item)
                                             );
                                         }
-                                        ImplItemKind::Method(_, _) => {
+                                        ImplItemKind::Method(..) => {
                                             // If this is a trait impl, ensure the method
                                             // exists in trait
                                             this.check_trait_item(impl_item.ident,
@@ -3878,6 +3922,49 @@ fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) {
                 visit::walk_expr(self, expr);
                 self.current_type_ascription.pop();
             }
+            // Resolve the body of async exprs inside the async closure to which they desugar
+            ExprKind::Async(_, async_closure_id, ref block) => {
+                let rib_kind = ClosureRibKind(async_closure_id);
+                self.ribs[ValueNS].push(Rib::new(rib_kind));
+                self.label_ribs.push(Rib::new(rib_kind));
+                self.visit_block(&block);
+                self.label_ribs.pop();
+                self.ribs[ValueNS].pop();
+            }
+            // `async |x| ...` gets desugared to `|x| future_from_generator(|| ...)`, so we need to
+            // resolve the arguments within the proper scopes so that usages of them inside the
+            // closure are detected as upvars rather than normal closure arg usages.
+            ExprKind::Closure(
+                _, IsAsync::Async(inner_closure_id), _, ref fn_decl, ref body, _span) =>
+            {
+                let rib_kind = ClosureRibKind(expr.id);
+                self.ribs[ValueNS].push(Rib::new(rib_kind));
+                self.label_ribs.push(Rib::new(rib_kind));
+                // Resolve arguments:
+                let mut bindings_list = FxHashMap();
+                for argument in &fn_decl.inputs {
+                    self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list);
+                    self.visit_ty(&argument.ty);
+                }
+                // No need to resolve return type-- the outer closure return type is
+                // FunctionRetTy::Default
+
+                // Now resolve the inner closure
+                {
+                    let rib_kind = ClosureRibKind(inner_closure_id);
+                    self.ribs[ValueNS].push(Rib::new(rib_kind));
+                    self.label_ribs.push(Rib::new(rib_kind));
+                    // No need to resolve arguments: the inner closure has none.
+                    // Resolve the return type:
+                    visit::walk_fn_ret_ty(self, &fn_decl.output);
+                    // Resolve the body
+                    self.visit_expr(body);
+                    self.label_ribs.pop();
+                    self.ribs[ValueNS].pop();
+                }
+                self.label_ribs.pop();
+                self.ribs[ValueNS].pop();
+            }
             _ => {
                 visit::walk_expr(self, expr);
             }
index de7a3dc5ceeb273f061bab2c5338a777a300b024..ebdaa456170b215a33bd16d653d040821e8fd934 100644 (file)
@@ -23,8 +23,8 @@
 use syntax::errors::DiagnosticBuilder;
 use syntax::ext::base::{self, Annotatable, Determinacy, MultiModifier, MultiDecorator};
 use syntax::ext::base::{MacroKind, SyntaxExtension, Resolver as SyntaxResolver};
-use syntax::ext::expand::{Expansion, ExpansionKind, Invocation, InvocationKind, find_attr_invoc};
-use syntax::ext::hygiene::{self, Mark, MarkKind};
+use syntax::ext::expand::{self, AstFragment, AstFragmentKind, Invocation, InvocationKind};
+use syntax::ext::hygiene::{self, Mark, Transparency};
 use syntax::ext::placeholders::placeholder;
 use syntax::ext::tt::macro_rules;
 use syntax::feature_gate::{self, emit_feature_err, GateIssue};
@@ -187,9 +187,10 @@ fn is_whitelisted_legacy_custom_derive(&self, name: Name) -> bool {
         self.whitelisted_legacy_custom_derives.contains(&name)
     }
 
-    fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion, derives: &[Mark]) {
+    fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
+                                            derives: &[Mark]) {
         let invocation = self.invocations[&mark];
-        self.collect_def_ids(mark, invocation, expansion);
+        self.collect_def_ids(mark, invocation, fragment);
 
         self.current_module = invocation.module.get();
         self.current_module.unresolved_invocations.borrow_mut().remove(&mark);
@@ -202,7 +203,7 @@ fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion, derives: &[Mark
             legacy_scope: LegacyScope::Invocation(invocation),
             expansion: mark,
         };
-        expansion.visit_with(&mut visitor);
+        fragment.visit_with(&mut visitor);
         invocation.expansion.set(visitor.legacy_scope);
     }
 
@@ -326,14 +327,15 @@ fn resolve_invoc(&mut self, invoc: &mut Invocation, scope: Mark, force: bool)
         self.macro_defs.insert(invoc.expansion_data.mark, 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.definitions.add_parent_module_of_macro_def(invoc.expansion_data.mark,
+                                                        normal_module_def_id);
 
         self.unused_macros.remove(&def_id);
         let ext = self.get_macro(def);
         if ext.is_modern() {
-            invoc.expansion_data.mark.set_kind(MarkKind::Modern);
+            invoc.expansion_data.mark.set_transparency(Transparency::Opaque);
         } else if def_id.krate == BUILTIN_MACROS_CRATE {
-            invoc.expansion_data.mark.set_kind(MarkKind::Builtin);
+            invoc.expansion_data.mark.set_is_builtin(true);
         }
         Ok(Some(ext))
     }
@@ -396,14 +398,14 @@ fn resolve_invoc_to_def(&mut self, invoc: &mut Invocation, scope: Mark, force: b
                 Ok(ext) => if let SyntaxExtension::ProcMacroDerive(_, ref inert_attrs, _) = *ext {
                     if inert_attrs.contains(&attr_name) {
                         // FIXME(jseyfried) Avoid `mem::replace` here.
-                        let dummy_item = placeholder(ExpansionKind::Items, ast::DUMMY_NODE_ID)
+                        let dummy_item = placeholder(AstFragmentKind::Items, ast::DUMMY_NODE_ID)
                             .make_items().pop().unwrap();
                         let dummy_item = Annotatable::Item(dummy_item);
                         *item = mem::replace(item, dummy_item).map_attrs(|mut attrs| {
                             let inert_attr = attr.take().unwrap();
                             attr::mark_known(&inert_attr);
                             if self.proc_macro_enabled {
-                                *attr = find_attr_invoc(&mut attrs);
+                                *attr = expand::find_attr_invoc(&mut attrs);
                             }
                             attrs.push(inert_attr);
                             attrs
@@ -437,8 +439,8 @@ fn resolve_macro_to_def(&mut self, scope: Mark, path: &ast::Path, kind: MacroKin
         let def = self.resolve_macro_to_def_inner(scope, path, kind, force);
         if def != Err(Determinacy::Undetermined) {
             // Do not report duplicated errors on every undetermined resolution.
-            path.segments.iter().find(|segment| segment.parameters.is_some()).map(|segment| {
-                self.session.span_err(segment.parameters.as_ref().unwrap().span(),
+            path.segments.iter().find(|segment| segment.args.is_some()).map(|segment| {
+                self.session.span_err(segment.args.as_ref().unwrap().span(),
                                       "generic arguments in macro path");
             });
         }
@@ -769,7 +771,7 @@ fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
     fn collect_def_ids(&mut self,
                        mark: Mark,
                        invocation: &'a InvocationData<'a>,
-                       expansion: &Expansion) {
+                       fragment: &AstFragment) {
         let Resolver { ref mut invocations, arenas, graph_root, .. } = *self;
         let InvocationData { def_index, .. } = *invocation;
 
@@ -787,7 +789,7 @@ fn collect_def_ids(&mut self,
         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| {
-            expansion.visit_with(def_collector)
+            fragment.visit_with(def_collector)
         });
     }
 
index 279ee403cc6258d5b6e702a6fa55986bd32569b7..262c0e40abc549788d487b01c192a83e6bdbfd33 100644 (file)
@@ -370,35 +370,38 @@ fn process_generic_params(
         id: NodeId,
     ) {
         for param in &generics.params {
-            if let ast::GenericParam::Type(ref ty_param) = *param {
-                let param_ss = ty_param.ident.span;
-                let name = escape(self.span.snippet(param_ss));
-                // Append $id to name to make sure each one is unique
-                let qualname = format!("{}::{}${}", prefix, name, id);
-                if !self.span.filter_generated(Some(param_ss), full_span) {
-                    let id = ::id_from_node_id(ty_param.id, &self.save_ctxt);
-                    let span = self.span_from_span(param_ss);
+            match param.kind {
+                ast::GenericParamKind::Lifetime { .. } => {}
+                ast::GenericParamKind::Type { .. } => {
+                    let param_ss = param.ident.span;
+                    let name = escape(self.span.snippet(param_ss));
+                    // Append $id to name to make sure each one is unique.
+                    let qualname = format!("{}::{}${}", prefix, name, id);
+                    if !self.span.filter_generated(Some(param_ss), full_span) {
+                        let id = ::id_from_node_id(param.id, &self.save_ctxt);
+                        let span = self.span_from_span(param_ss);
 
-                    self.dumper.dump_def(
-                        &Access {
-                            public: false,
-                            reachable: false,
-                        },
-                        Def {
-                            kind: DefKind::Type,
-                            id,
-                            span,
-                            name,
-                            qualname,
-                            value: String::new(),
-                            parent: None,
-                            children: vec![],
-                            decl_id: None,
-                            docs: String::new(),
-                            sig: None,
-                            attributes: vec![],
-                        },
-                    );
+                        self.dumper.dump_def(
+                            &Access {
+                                public: false,
+                                reachable: false,
+                            },
+                            Def {
+                                kind: DefKind::Type,
+                                id,
+                                span,
+                                name,
+                                qualname,
+                                value: String::new(),
+                                parent: None,
+                                children: vec![],
+                                decl_id: None,
+                                docs: String::new(),
+                                sig: None,
+                                attributes: vec![],
+                            },
+                        );
+                    }
                 }
             }
         }
@@ -715,7 +718,7 @@ fn process_trait(
         &mut self,
         item: &'l ast::Item,
         generics: &'l ast::Generics,
-        trait_refs: &'l ast::TyParamBounds,
+        trait_refs: &'l ast::GenericBounds,
         methods: &'l [ast::TraitItem],
     ) {
         let name = item.ident.to_string();
@@ -758,10 +761,8 @@ fn process_trait(
         // super-traits
         for super_bound in trait_refs.iter() {
             let trait_ref = match *super_bound {
-                ast::TraitTyParamBound(ref trait_ref, _) => trait_ref,
-                ast::RegionTyParamBound(..) => {
-                    continue;
-                }
+                ast::GenericBound::Trait(ref trait_ref, _) => trait_ref,
+                ast::GenericBound::Outlives(..) => continue,
             };
 
             let trait_ref = &trait_ref.trait_ref;
@@ -818,14 +819,17 @@ fn process_path(&mut self, id: NodeId, path: &'l ast::Path) {
         }
         self.dump_path_ref(id, path);
 
-        // Type parameters
+        // Type arguments
         for seg in &path.segments {
-            if let Some(ref params) = seg.parameters {
-                match **params {
-                    ast::PathParameters::AngleBracketed(ref data) => for t in &data.types {
-                        self.visit_ty(t);
-                    },
-                    ast::PathParameters::Parenthesized(ref data) => {
+            if let Some(ref generic_args) = seg.args {
+                match **generic_args {
+                    ast::GenericArgs::AngleBracketed(ref data) => {
+                        data.args.iter().for_each(|arg| match arg {
+                            ast::GenericArg::Type(ty) => self.visit_ty(ty),
+                            _ => {}
+                        });
+                    }
+                    ast::GenericArgs::Parenthesized(ref data) => {
                         for t in &data.inputs {
                             self.visit_ty(t);
                         }
@@ -905,11 +909,12 @@ fn process_method_call(
         }
 
         // Explicit types in the turbo-fish.
-        if let Some(ref params) = seg.parameters {
-            if let ast::PathParameters::AngleBracketed(ref data) = **params {
-                for t in &data.types {
-                    self.visit_ty(t);
-                }
+        if let Some(ref generic_args) = seg.args {
+            if let ast::GenericArgs::AngleBracketed(ref data) = **generic_args {
+                data.args.iter().for_each(|arg| match arg {
+                    ast::GenericArg::Type(ty) => self.visit_ty(ty),
+                    _ => {}
+                });
             }
         }
 
@@ -1478,18 +1483,19 @@ fn visit_item(&mut self, item: &'l ast::Item) {
     }
 
     fn visit_generics(&mut self, generics: &'l ast::Generics) {
-        for param in &generics.params {
-            if let ast::GenericParam::Type(ref ty_param) = *param {
-                for bound in ty_param.bounds.iter() {
-                    if let ast::TraitTyParamBound(ref trait_ref, _) = *bound {
+        generics.params.iter().for_each(|param| match param.kind {
+            ast::GenericParamKind::Lifetime { .. } => {}
+            ast::GenericParamKind::Type { ref default, .. } => {
+                for bound in &param.bounds {
+                    if let ast::GenericBound::Trait(ref trait_ref, _) = *bound {
                         self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path)
                     }
                 }
-                if let Some(ref ty) = ty_param.default {
+                if let Some(ref ty) = default {
                     self.visit_ty(&ty);
                 }
             }
-        }
+        });
     }
 
     fn visit_ty(&mut self, t: &'l ast::Ty) {
@@ -1549,7 +1555,7 @@ fn visit_expr(&mut self, ex: &'l ast::Expr) {
                     }
                 }
             }
-            ast::ExprKind::Closure(_, _, ref decl, ref body, _fn_decl_span) => {
+            ast::ExprKind::Closure(_, _, _, ref decl, ref body, _fn_decl_span) => {
                 let mut id = String::from("$");
                 id.push_str(&ex.id.to_string());
 
index f9510970e43d44edb2a753b8dbfd6f785c56a586..deb91774175667d148bc7b79a7f48b1f1990c940 100644 (file)
@@ -692,8 +692,8 @@ fn fn_type(path: &ast::Path) -> bool {
             if path.segments.len() != 1 {
                 return false;
             }
-            if let Some(ref params) = path.segments[0].parameters {
-                if let ast::PathParameters::Parenthesized(_) = **params {
+            if let Some(ref generic_args) = path.segments[0].args {
+                if let ast::GenericArgs::Parenthesized(_) = **generic_args {
                     return true;
                 }
             }
@@ -844,7 +844,7 @@ pub fn get_macro_use_data(&self, span: Span) -> Option<MacroRef> {
         let callsite = span.source_callsite();
         let callsite_span = self.span_from_span(callsite);
         let callee = span.source_callee()?;
-        let callee_span = callee.span?;
+        let callee_span = callee.def_site?;
 
         // Ignore attribute macros, their spans are usually mangled
         if let MacroAttribute(_) = callee.format {
@@ -872,7 +872,7 @@ pub fn get_macro_use_data(&self, span: Span) -> Option<MacroRef> {
         let callee_span = self.span_from_span(callee_span);
         Some(MacroRef {
             span: callsite_span,
-            qualname: callee.name().to_string(), // FIXME: generate the real qualname
+            qualname: callee.format.name().to_string(), // FIXME: generate the real qualname
             callee_span,
         })
     }
@@ -934,10 +934,7 @@ fn make_signature(decl: &ast::FnDecl, generics: &ast::Generics) -> String {
         sig.push_str(&generics
             .params
             .iter()
-            .map(|param| match *param {
-                ast::GenericParam::Lifetime(ref l) => l.lifetime.ident.name.to_string(),
-                ast::GenericParam::Type(ref t) => t.ident.to_string(),
-            })
+            .map(|param| param.ident.to_string())
             .collect::<Vec<_>>()
             .join(", "));
         sig.push_str("> ");
index e3545e8f1a9b8e2a931c7d99ea5cfa08449f46dc..9f2ca20276cdc00910a12e149932f41fc88fb0cc 100644 (file)
@@ -104,7 +104,7 @@ pub fn assoc_const_signature(
 pub fn assoc_type_signature(
     id: NodeId,
     ident: ast::Ident,
-    bounds: Option<&ast::TyParamBounds>,
+    bounds: Option<&ast::GenericBounds>,
     default: Option<&ast::Ty>,
     scx: &SaveContext,
 ) -> Option<Signature> {
@@ -223,9 +223,9 @@ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext) ->
                     text.push_str("for<");
                     text.push_str(&f.generic_params
                         .iter()
-                        .filter_map(|p| match *p {
-                            ast::GenericParam::Lifetime(ref l) => {
-                                Some(l.lifetime.ident.to_string())
+                        .filter_map(|param| match param.kind {
+                            ast::GenericParamKind::Lifetime { .. } => {
+                                Some(param.ident.to_string())
                             }
                             _ => None,
                         })
@@ -380,17 +380,20 @@ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext) ->
 
                 Ok(extend_sig(ty, text, defs, vec![]))
             }
-            ast::ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, _) => {
+            ast::ItemKind::Fn(ref decl, header, ref generics, _) => {
                 let mut text = String::new();
-                if constness.node == ast::Constness::Const {
+                if header.constness.node == ast::Constness::Const {
                     text.push_str("const ");
                 }
-                if unsafety == ast::Unsafety::Unsafe {
+                if header.asyncness.is_async() {
+                    text.push_str("async ");
+                }
+                if header.unsafety == ast::Unsafety::Unsafe {
                     text.push_str("unsafe ");
                 }
-                if abi != ::rustc_target::spec::abi::Abi::Rust {
+                if header.abi != ::rustc_target::spec::abi::Abi::Rust {
                     text.push_str("extern");
-                    text.push_str(&abi.to_string());
+                    text.push_str(&header.abi.to_string());
                     text.push(' ');
                 }
                 text.push_str("fn ");
@@ -617,45 +620,34 @@ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext) ->
 
         let mut defs = vec![];
         for param in &self.params {
-            match *param {
-                ast::GenericParam::Lifetime(ref l) => {
-                    let mut l_text = l.lifetime.ident.to_string();
-                    defs.push(SigElement {
-                        id: id_from_node_id(l.lifetime.id, scx),
-                        start: offset + text.len(),
-                        end: offset + text.len() + l_text.len(),
-                    });
-
-                    if !l.bounds.is_empty() {
-                        l_text.push_str(": ");
-                        let bounds = l.bounds
-                            .iter()
-                            .map(|l| l.ident.to_string())
+            let mut param_text = param.ident.to_string();
+            defs.push(SigElement {
+                id: id_from_node_id(param.id, scx),
+                start: offset + text.len(),
+                end: offset + text.len() + param_text.len(),
+            });
+            if !param.bounds.is_empty() {
+                param_text.push_str(": ");
+                match param.kind {
+                    ast::GenericParamKind::Lifetime { .. } => {
+                        let bounds = param.bounds.iter()
+                            .map(|bound| match bound {
+                                ast::GenericBound::Outlives(lt) => lt.ident.to_string(),
+                                _ => panic!(),
+                            })
                             .collect::<Vec<_>>()
                             .join(" + ");
-                        l_text.push_str(&bounds);
+                        param_text.push_str(&bounds);
                         // FIXME add lifetime bounds refs.
                     }
-                    text.push_str(&l_text);
-                    text.push(',');
-                }
-                ast::GenericParam::Type(ref t) => {
-                    let mut t_text = t.ident.to_string();
-                    defs.push(SigElement {
-                        id: id_from_node_id(t.id, scx),
-                        start: offset + text.len(),
-                        end: offset + text.len() + t_text.len(),
-                    });
-
-                    if !t.bounds.is_empty() {
-                        t_text.push_str(": ");
-                        t_text.push_str(&pprust::bounds_to_string(&t.bounds));
+                    ast::GenericParamKind::Type { .. } => {
+                        param_text.push_str(&pprust::bounds_to_string(&param.bounds));
                         // FIXME descend properly into bounds.
                     }
-                    text.push_str(&t_text);
-                    text.push(',');
                 }
             }
+            text.push_str(&param_text);
+            text.push(',');
         }
 
         text.push('>');
@@ -852,7 +844,7 @@ fn name_and_generics(
 fn make_assoc_type_signature(
     id: NodeId,
     ident: ast::Ident,
-    bounds: Option<&ast::TyParamBounds>,
+    bounds: Option<&ast::GenericBounds>,
     default: Option<&ast::Ty>,
     scx: &SaveContext,
 ) -> Result {
@@ -925,15 +917,18 @@ fn make_method_signature(
 ) -> Result {
     // FIXME code dup with function signature
     let mut text = String::new();
-    if m.constness.node == ast::Constness::Const {
+    if m.header.constness.node == ast::Constness::Const {
         text.push_str("const ");
     }
-    if m.unsafety == ast::Unsafety::Unsafe {
+    if m.header.asyncness.is_async() {
+        text.push_str("async ");
+    }
+    if m.header.unsafety == ast::Unsafety::Unsafe {
         text.push_str("unsafe ");
     }
-    if m.abi != ::rustc_target::spec::abi::Abi::Rust {
+    if m.header.abi != ::rustc_target::spec::abi::Abi::Rust {
         text.push_str("extern");
-        text.push_str(&m.abi.to_string());
+        text.push_str(&m.header.abi.to_string());
         text.push(' ');
     }
     text.push_str("fn ");
index bf26409c3ef5fa858cb932f967eb5e1b8a485347..a1242621cb18c5882197fd25c265bad632b7bac6 100644 (file)
     Canonical, CanonicalVarValues, Canonicalize, QueryRegionConstraint, QueryResult,
 };
 use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
-use rustc::traits::{DomainGoal, ExClauseFold, ExClauseLift, Goal, ProgramClause, QuantifierKind};
+use rustc::traits::{
+    WellFormed,
+    FromEnv,
+    DomainGoal,
+    ExClauseFold,
+    ExClauseLift,
+    Goal,
+    ProgramClause,
+    QuantifierKind
+};
 use rustc::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 use rustc::ty::subst::Kind;
 use rustc::ty::{self, TyCtxt};
@@ -314,11 +323,10 @@ fn program_clauses(
         _environment: &ty::ParamEnv<'tcx>,
         goal: &DomainGoal<'tcx>,
     ) -> Vec<ProgramClause<'tcx>> {
-        use rustc::traits::DomainGoal::*;
-        use rustc::traits::WhereClauseAtom::*;
+        use rustc::traits::WhereClause::*;
 
         match goal {
-            Holds(Implemented(_trait_predicate)) => {
+            DomainGoal::Holds(Implemented(_trait_predicate)) => {
                 // These come from:
                 //
                 // - Trait definitions (implied bounds)
@@ -326,31 +334,31 @@ fn program_clauses(
                 panic!()
             }
 
-            Holds(ProjectionEq(_projection_predicate)) => {
+            DomainGoal::Holds(ProjectionEq(_projection_predicate)) => {
                 // These come from:
                 panic!()
             }
 
-            WellFormed(Implemented(_trait_predicate)) => {
-                // These come from -- the trait decl.
+            DomainGoal::Holds(RegionOutlives(_region_outlives)) => {
                 panic!()
             }
 
-            WellFormed(ProjectionEq(_projection_predicate)) => panic!(),
-
-            FromEnv(Implemented(_trait_predicate)) => panic!(),
-
-            FromEnv(ProjectionEq(_projection_predicate)) => panic!(),
+            DomainGoal::Holds(TypeOutlives(_type_outlives)) => {
+                panic!()
+            }
 
-            WellFormedTy(_ty) => panic!(),
+            DomainGoal::WellFormed(WellFormed::Trait(_trait_predicate)) => {
+                // These come from -- the trait decl.
+                panic!()
+            }
 
-            FromEnvTy(_ty) => panic!(),
+            DomainGoal::WellFormed(WellFormed::Ty(_ty)) => panic!(),
 
-            RegionOutlives(_region_outlives) => panic!(),
+            DomainGoal::FromEnv(FromEnv::Trait(_trait_predicate)) => panic!(),
 
-            TypeOutlives(_type_outlives) => panic!(),
+            DomainGoal::FromEnv(FromEnv::Ty(_ty)) => panic!(),
 
-            Normalize(_) => panic!(),
+            DomainGoal::Normalize(_) => panic!(),
         }
     }
 
index 32f18a62abe596cd83289a169725b25b35516a11..0270e970976eaa59906bccbfda1f1783ee4e462c 100644 (file)
@@ -13,7 +13,7 @@
 use rustc::hir::map::definitions::DefPathData;
 use rustc::hir::{self, ImplPolarity};
 use rustc::traits::{Clause, Clauses, DomainGoal, Goal, PolyDomainGoal, ProgramClause,
-                    WhereClauseAtom};
+                    WhereClause, FromEnv, WellFormed};
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, Slice, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
@@ -23,7 +23,7 @@
 use std::iter;
 
 crate trait Lower<T> {
-    /// Lower a rustc construction (e.g. `ty::TraitPredicate`) to a chalk-like type.
+    /// Lower a rustc construct (e.g. `ty::TraitPredicate`) to a chalk-like type.
     fn lower(&self) -> T;
 }
 
@@ -36,36 +36,36 @@ fn lower(&self) -> Vec<U> {
     }
 }
 
-impl<'tcx> Lower<WhereClauseAtom<'tcx>> for ty::TraitPredicate<'tcx> {
-    fn lower(&self) -> WhereClauseAtom<'tcx> {
-        WhereClauseAtom::Implemented(*self)
+impl<'tcx> Lower<WhereClause<'tcx>> for ty::TraitPredicate<'tcx> {
+    fn lower(&self) -> WhereClause<'tcx> {
+        WhereClause::Implemented(*self)
     }
 }
 
-impl<'tcx> Lower<WhereClauseAtom<'tcx>> for ty::ProjectionPredicate<'tcx> {
-    fn lower(&self) -> WhereClauseAtom<'tcx> {
-        WhereClauseAtom::ProjectionEq(*self)
+impl<'tcx> Lower<WhereClause<'tcx>> for ty::ProjectionPredicate<'tcx> {
+    fn lower(&self) -> WhereClause<'tcx> {
+        WhereClause::ProjectionEq(*self)
     }
 }
 
-impl<'tcx, T> Lower<DomainGoal<'tcx>> for T
-where
-    T: Lower<WhereClauseAtom<'tcx>>,
-{
-    fn lower(&self) -> DomainGoal<'tcx> {
-        DomainGoal::Holds(self.lower())
+impl<'tcx> Lower<WhereClause<'tcx>> for ty::RegionOutlivesPredicate<'tcx> {
+    fn lower(&self) -> WhereClause<'tcx> {
+        WhereClause::RegionOutlives(*self)
     }
 }
 
-impl<'tcx> Lower<DomainGoal<'tcx>> for ty::RegionOutlivesPredicate<'tcx> {
-    fn lower(&self) -> DomainGoal<'tcx> {
-        DomainGoal::RegionOutlives(*self)
+impl<'tcx> Lower<WhereClause<'tcx>> for ty::TypeOutlivesPredicate<'tcx> {
+    fn lower(&self) -> WhereClause<'tcx> {
+        WhereClause::TypeOutlives(*self)
     }
 }
 
-impl<'tcx> Lower<DomainGoal<'tcx>> for ty::TypeOutlivesPredicate<'tcx> {
+impl<'tcx, T> Lower<DomainGoal<'tcx>> for T
+where
+    T: Lower<WhereClause<'tcx>>,
+{
     fn lower(&self) -> DomainGoal<'tcx> {
-        DomainGoal::TypeOutlives(*self)
+        DomainGoal::Holds(self.lower())
     }
 }
 
@@ -86,15 +86,20 @@ fn lower(&self) -> PolyDomainGoal<'tcx> {
 
 impl<'tcx> Lower<PolyDomainGoal<'tcx>> for ty::Predicate<'tcx> {
     fn lower(&self) -> PolyDomainGoal<'tcx> {
-        use rustc::ty::Predicate::*;
+        use rustc::ty::Predicate;
 
         match self {
-            Trait(predicate) => predicate.lower(),
-            RegionOutlives(predicate) => predicate.lower(),
-            TypeOutlives(predicate) => predicate.lower(),
-            Projection(predicate) => predicate.lower(),
-            WellFormed(ty) => ty::Binder::dummy(DomainGoal::WellFormedTy(*ty)),
-            ObjectSafe(..) | ClosureKind(..) | Subtype(..) | ConstEvaluatable(..) => {
+            Predicate::Trait(predicate) => predicate.lower(),
+            Predicate::RegionOutlives(predicate) => predicate.lower(),
+            Predicate::TypeOutlives(predicate) => predicate.lower(),
+            Predicate::Projection(predicate) => predicate.lower(),
+            Predicate::WellFormed(ty) => ty::Binder::dummy(
+                DomainGoal::WellFormed(WellFormed::Ty(*ty))
+            ),
+            Predicate::ObjectSafe(..) |
+            Predicate::ClosureKind(..) |
+            Predicate::Subtype(..) |
+            Predicate::ConstEvaluatable(..) => {
                 unimplemented!()
             }
         }
@@ -110,11 +115,13 @@ trait IntoFromEnvGoal {
 
 impl<'tcx> IntoFromEnvGoal for DomainGoal<'tcx> {
     fn into_from_env_goal(self) -> DomainGoal<'tcx> {
-        use self::DomainGoal::*;
+        use self::WhereClause::*;
+
         match self {
-            Holds(wc_atom) => FromEnv(wc_atom),
-            WellFormed(..) | FromEnv(..) | WellFormedTy(..) | FromEnvTy(..) | Normalize(..)
-            | RegionOutlives(..) | TypeOutlives(..) => self,
+            DomainGoal::Holds(Implemented(trait_ref)) => DomainGoal::FromEnv(
+                FromEnv::Trait(trait_ref)
+            ),
+            other => other,
         }
     }
 }
@@ -127,6 +134,8 @@ fn into_from_env_goal(self) -> DomainGoal<'tcx> {
         DefPathData::Trait(_) => program_clauses_for_trait(tcx, def_id),
         DefPathData::Impl => program_clauses_for_impl(tcx, def_id),
         DefPathData::AssocTypeInImpl(..) => program_clauses_for_associated_type_value(tcx, def_id),
+        DefPathData::AssocTypeInTrait(..) => program_clauses_for_associated_type_def(tcx, def_id),
+        DefPathData::TypeNs(..) => program_clauses_for_type_def(tcx, def_id),
         _ => Slice::empty(),
     }
 }
@@ -212,16 +221,20 @@ fn program_clauses_for_trait<'a, 'tcx>(
             substs: Substs::identity_for_item(tcx, def_id),
         },
     };
-    // `FromEnv(Self: Trait<P1..Pn>)`
-    let from_env = Goal::from(DomainGoal::FromEnv(trait_pred.lower()));
+
     // `Implemented(Self: Trait<P1..Pn>)`
-    let impl_trait = DomainGoal::Holds(WhereClauseAtom::Implemented(trait_pred));
+    let impl_trait: DomainGoal = trait_pred.lower();
+
+     // `FromEnv(Self: Trait<P1..Pn>)`
+    let from_env_goal = impl_trait.into_from_env_goal().into_goal();
+    let hypotheses = tcx.intern_goals(&[from_env_goal]);
 
     // `Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)`
     let implemented_from_env = ProgramClause {
         goal: impl_trait,
-        hypotheses: tcx.intern_goals(&[from_env]),
+        hypotheses,
     };
+
     let clauses = iter::once(Clause::ForAll(ty::Binder::dummy(implemented_from_env)));
 
     // Rule Implied-Bound-From-Trait
@@ -239,25 +252,17 @@ fn program_clauses_for_trait<'a, 'tcx>(
     let where_clauses = &tcx.predicates_of(def_id).predicates;
     let implied_bound_clauses = where_clauses[1..]
         .into_iter()
-        .map(|wc| implied_bound_from_trait(tcx, trait_pred, wc));
+        .map(|wc| wc.lower())
 
-    tcx.mk_clauses(clauses.chain(implied_bound_clauses))
-}
+        // `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`
+        .map(|wc| wc.map_bound(|goal| ProgramClause {
+            goal: goal.into_from_env_goal(),
+            hypotheses,
+        }))
 
-/// For a given `where_clause`, returns a clause `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`.
-fn implied_bound_from_trait<'a, 'tcx>(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    trait_pred: ty::TraitPredicate<'tcx>,
-    where_clause: &ty::Predicate<'tcx>,
-) -> Clause<'tcx> {
-    // `FromEnv(Self: Trait<P1..Pn>)`
-    let impl_trait = DomainGoal::FromEnv(WhereClauseAtom::Implemented(trait_pred));
-
-    // `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`
-    Clause::ForAll(where_clause.lower().map_bound(|goal| ProgramClause {
-        goal: goal.into_from_env_goal(),
-        hypotheses: tcx.intern_goals(&[Goal::from(impl_trait)]),
-    }))
+        .map(Clause::ForAll);
+
+    tcx.mk_clauses(clauses.chain(implied_bound_clauses))
 }
 
 fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Clauses<'tcx> {
@@ -275,9 +280,11 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId
     // }
     // ```
 
-    let trait_ref = tcx.impl_trait_ref(def_id).unwrap();
+    let trait_ref = tcx.impl_trait_ref(def_id).expect("not an impl");
+
     // `Implemented(A0: Trait<A1..An>)`
     let trait_pred = ty::TraitPredicate { trait_ref }.lower();
+
     // `WC`
     let where_clauses = tcx.predicates_of(def_id).predicates.lower();
 
@@ -293,6 +300,72 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId
     tcx.intern_clauses(&[Clause::ForAll(ty::Binder::dummy(clause))])
 }
 
+pub fn program_clauses_for_type_def<'a, 'tcx>(
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    def_id: DefId,
+) -> Clauses<'tcx> {
+
+    // Rule WellFormed-Type
+    //
+    // `struct Ty<P1..Pn> where WC1, ..., WCm`
+    //
+    // ```
+    // forall<P1..Pn> {
+    //   WellFormed(Ty<...>) :- WC1, ..., WCm`
+    // }
+    // ```
+
+    // `Ty<...>`
+    let ty = tcx.type_of(def_id);
+
+    // `WC`
+    let where_clauses = tcx.predicates_of(def_id).predicates.lower();
+
+    // `WellFormed(Ty<...>) :- WC1, ..., WCm`
+    let well_formed = ProgramClause {
+        goal: DomainGoal::WellFormed(WellFormed::Ty(ty)),
+        hypotheses: tcx.mk_goals(
+            where_clauses.iter().cloned().map(|wc| Goal::from_poly_domain_goal(wc, tcx))
+        ),
+    };
+
+    let well_formed_clause = iter::once(Clause::ForAll(ty::Binder::dummy(well_formed)));
+
+    // Rule FromEnv-Type
+    //
+    // For each where clause `WC`:
+    // ```
+    // forall<P1..Pn> {
+    //   FromEnv(WC) :- FromEnv(Ty<...>)
+    // }
+    // ```
+
+    // `FromEnv(Ty<...>)`
+    let from_env_goal = DomainGoal::FromEnv(FromEnv::Ty(ty)).into_goal();
+    let hypotheses = tcx.intern_goals(&[from_env_goal]);
+
+    // For each where clause `WC`:
+    let from_env_clauses = where_clauses
+        .into_iter()
+
+        // `FromEnv(WC) :- FromEnv(Ty<...>)`
+        .map(|wc| wc.map_bound(|goal| ProgramClause {
+            goal: goal.into_from_env_goal(),
+            hypotheses,
+        }))
+
+        .map(Clause::ForAll);
+
+    tcx.mk_clauses(well_formed_clause.chain(from_env_clauses))
+}
+
+pub fn program_clauses_for_associated_type_def<'a, 'tcx>(
+    _tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    _item_id: DefId,
+) -> Clauses<'tcx> {
+    unimplemented!()
+}
+
 pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     item_id: DefId,
@@ -301,45 +374,50 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
     //
     // ```impl<P0..Pn> Trait<A1..An> for A0
     // {
-    //     type AssocType<Pn+1..Pm> where WC = T;
+    //     type AssocType<Pn+1..Pm> = T;
     // }```
     //
+    // FIXME: For the moment, we don't account for where clauses written on the associated
+    // ty definition (i.e. in the trait def, as in `type AssocType<T> where T: Sized`).
     // ```
     // forall<P0..Pm> {
     //   forall<Pn+1..Pm> {
     //     Normalize(<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm> -> T) :-
-    //       Implemented(A0: Trait<A1..An>) && WC
+    //       Implemented(A0: Trait<A1..An>)
     //   }
     // }
     // ```
 
     let item = tcx.associated_item(item_id);
     debug_assert_eq!(item.kind, ty::AssociatedKind::Type);
-    let impl_id = if let ty::AssociatedItemContainer::ImplContainer(impl_id) = item.container {
-        impl_id
-    } else {
-        bug!()
+    let impl_id = match item.container {
+        ty::AssociatedItemContainer::ImplContainer(impl_id) => impl_id,
+        _ => bug!("not an impl container"),
     };
+
     // `A0 as Trait<A1..An>`
     let trait_ref = tcx.impl_trait_ref(impl_id).unwrap();
+
     // `T`
     let ty = tcx.type_of(item_id);
+
     // `Implemented(A0: Trait<A1..An>)`
     let trait_implemented = ty::Binder::dummy(ty::TraitPredicate { trait_ref }.lower());
-    // `WC`
-    let item_where_clauses = tcx.predicates_of(item_id).predicates.lower();
-    // `Implemented(A0: Trait<A1..An>) && WC`
-    let mut where_clauses = vec![trait_implemented];
-    where_clauses.extend(item_where_clauses);
+
+    // `Implemented(A0: Trait<A1..An>)`
+    let hypotheses = vec![trait_implemented];
+
     // `<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm>`
     let projection_ty = ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, item.name);
+
     // `Normalize(<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm> -> T)`
     let normalize_goal = DomainGoal::Normalize(ty::ProjectionPredicate { projection_ty, ty });
+
     // `Normalize(... -> T) :- ...`
     let clause = ProgramClause {
         goal: normalize_goal,
         hypotheses: tcx.mk_goals(
-            where_clauses
+            hypotheses
                 .into_iter()
                 .map(|wc| Goal::from_poly_domain_goal(wc, tcx)),
         ),
index 18911b47ed1d08434ac9ba141d56d92bacef8980..f3912c3042d7fceef539782e094ed0dcf2aa18d4 100644 (file)
@@ -13,7 +13,7 @@
 //! is parameterized by an instance of `AstConv`.
 
 use rustc_data_structures::accumulate_vec::AccumulateVec;
-use hir;
+use hir::{self, GenericArg};
 use hir::def::Def;
 use hir::def_id::DefId;
 use middle::resolve_lifetime as rl;
@@ -177,11 +177,11 @@ pub fn ast_path_substs_for_ty(&self,
     {
 
         let (substs, assoc_bindings) =
-            item_segment.with_parameters(|parameters| {
+            item_segment.with_generic_args(|generic_args| {
                 self.create_substs_for_ast_path(
                     span,
                     def_id,
-                    parameters,
+                    generic_args,
                     item_segment.infer_types,
                     None)
             });
@@ -199,7 +199,7 @@ pub fn ast_path_substs_for_ty(&self,
     fn create_substs_for_ast_path(&self,
         span: Span,
         def_id: DefId,
-        parameters: &hir::PathParameters,
+        generic_args: &hir::GenericArgs,
         infer_types: bool,
         self_ty: Option<Ty<'tcx>>)
         -> (&'tcx Substs<'tcx>, Vec<ConvertedBinding<'tcx>>)
@@ -207,16 +207,26 @@ fn create_substs_for_ast_path(&self,
         let tcx = self.tcx();
 
         debug!("create_substs_for_ast_path(def_id={:?}, self_ty={:?}, \
-               parameters={:?})",
-               def_id, self_ty, parameters);
+               generic_args={:?})",
+               def_id, self_ty, generic_args);
 
         // If the type is parameterized by this region, then replace this
         // region with the current anon region binding (in other words,
         // whatever & would get replaced with).
-        let decl_generics = tcx.generics_of(def_id);
-        let ty_provided = parameters.types.len();
-        let lt_provided = parameters.lifetimes.len();
 
+        // FIXME(varkor): Separating out the parameters is messy.
+        let lifetimes: Vec<_> = generic_args.args.iter().filter_map(|arg| match arg {
+            GenericArg::Lifetime(lt) => Some(lt),
+            _ => None,
+        }).collect();
+        let types: Vec<_> = generic_args.args.iter().filter_map(|arg| match arg {
+            GenericArg::Type(ty) => Some(ty),
+            _ => None,
+        }).collect();
+        let lt_provided = lifetimes.len();
+        let ty_provided = types.len();
+
+        let decl_generics = tcx.generics_of(def_id);
         let mut lt_accepted = 0;
         let mut ty_params = ParamRange { required: 0, accepted: 0 };
         for param in &decl_generics.params {
@@ -269,8 +279,8 @@ fn create_substs_for_ast_path(&self,
             match param.kind {
                 GenericParamDefKind::Lifetime => {
                     let i = param.index as usize - own_self;
-                    if let Some(lifetime) = parameters.lifetimes.get(i) {
-                        self.ast_region_to_region(lifetime, Some(param)).into()
+                    if let Some(lt) = lifetimes.get(i) {
+                        self.ast_region_to_region(lt, Some(param)).into()
                     } else {
                         tcx.types.re_static.into()
                     }
@@ -286,7 +296,7 @@ fn create_substs_for_ast_path(&self,
                     let i = i - (lt_accepted + own_self);
                     if i < ty_provided {
                         // A provided type parameter.
-                        self.ast_ty_to_ty(&parameters.types[i]).into()
+                        self.ast_ty_to_ty(&types[i]).into()
                     } else if infer_types {
                         // No type parameters were provided, we can infer all.
                         if !default_needs_object_self(param) {
@@ -330,7 +340,7 @@ fn create_substs_for_ast_path(&self,
             }
         });
 
-        let assoc_bindings = parameters.bindings.iter().map(|binding| {
+        let assoc_bindings = generic_args.bindings.iter().map(|binding| {
             ConvertedBinding {
                 item_name: binding.name,
                 ty: self.ast_ty_to_ty(&binding.ty),
@@ -355,7 +365,7 @@ pub fn instantiate_mono_trait_ref(&self,
         self_ty: Ty<'tcx>)
         -> ty::TraitRef<'tcx>
     {
-        self.prohibit_type_params(trait_ref.path.segments.split_last().unwrap().1);
+        self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1);
 
         let trait_def_id = self.trait_def_id(trait_ref);
         self.ast_path_to_mono_trait_ref(trait_ref.path.span,
@@ -389,7 +399,7 @@ pub(super) fn instantiate_poly_trait_ref_inner(&self,
 
         debug!("ast_path_to_poly_trait_ref({:?}, def_id={:?})", trait_ref, trait_def_id);
 
-        self.prohibit_type_params(trait_ref.path.segments.split_last().unwrap().1);
+        self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1);
 
         let (substs, assoc_bindings) =
             self.create_substs_for_ast_trait_ref(trait_ref.path.span,
@@ -451,7 +461,8 @@ fn create_substs_for_ast_trait_ref(&self,
         let trait_def = self.tcx().trait_def(trait_def_id);
 
         if !self.tcx().features().unboxed_closures &&
-           trait_segment.with_parameters(|p| p.parenthesized) != trait_def.paren_sugar {
+            trait_segment.with_generic_args(|generic_args| generic_args.parenthesized)
+            != trait_def.paren_sugar {
             // For now, require that parenthetical notation be used only with `Fn()` etc.
             let msg = if trait_def.paren_sugar {
                 "the precise format of `Fn`-family traits' type parameters is subject to change. \
@@ -463,10 +474,10 @@ fn create_substs_for_ast_trait_ref(&self,
                              span, GateIssue::Language, msg);
         }
 
-        trait_segment.with_parameters(|parameters| {
+        trait_segment.with_generic_args(|generic_args| {
             self.create_substs_for_ast_path(span,
                                             trait_def_id,
-                                            parameters,
+                                            generic_args,
                                             trait_segment.infer_types,
                                             Some(self_ty))
         })
@@ -866,7 +877,7 @@ pub fn associated_path_def_to_ty(&self,
 
         debug!("associated_path_def_to_ty: {:?}::{}", ty, assoc_name);
 
-        self.prohibit_type_params(slice::from_ref(item_segment));
+        self.prohibit_generics(slice::from_ref(item_segment));
 
         // Find the type of the associated item, and the trait where the associated
         // item is declared.
@@ -943,7 +954,7 @@ fn qpath_to_ty(&self,
         let tcx = self.tcx();
         let trait_def_id = tcx.parent_def_id(item_def_id).unwrap();
 
-        self.prohibit_type_params(slice::from_ref(item_segment));
+        self.prohibit_generics(slice::from_ref(item_segment));
 
         let self_ty = if let Some(ty) = opt_self_ty {
             ty
@@ -968,25 +979,37 @@ fn qpath_to_ty(&self,
         self.normalize_ty(span, tcx.mk_projection(item_def_id, trait_ref.substs))
     }
 
-    pub fn prohibit_type_params(&self, segments: &[hir::PathSegment]) {
+    pub fn prohibit_generics(&self, segments: &[hir::PathSegment]) {
         for segment in segments {
-            segment.with_parameters(|parameters| {
-                for typ in &parameters.types {
-                    struct_span_err!(self.tcx().sess, typ.span, E0109,
-                                     "type parameters are not allowed on this type")
-                        .span_label(typ.span, "type parameter not allowed")
-                        .emit();
-                    break;
-                }
-                for lifetime in &parameters.lifetimes {
-                    struct_span_err!(self.tcx().sess, lifetime.span, E0110,
-                                     "lifetime parameters are not allowed on this type")
-                        .span_label(lifetime.span,
-                                    "lifetime parameter not allowed on this type")
-                        .emit();
-                    break;
+            segment.with_generic_args(|generic_args| {
+                let (mut err_for_lt, mut err_for_ty) = (false, false);
+                for arg in &generic_args.args {
+                    let (mut span_err, span, kind) = match arg {
+                        hir::GenericArg::Lifetime(lt) => {
+                            if err_for_lt { continue }
+                            err_for_lt = true;
+                            (struct_span_err!(self.tcx().sess, lt.span, E0110,
+                                            "lifetime parameters are not allowed on \
+                                                this type"),
+                             lt.span,
+                             "lifetime")
+                        }
+                        hir::GenericArg::Type(ty) => {
+                            if err_for_ty { continue }
+                            err_for_ty = true;
+                            (struct_span_err!(self.tcx().sess, ty.span, E0109,
+                                            "type parameters are not allowed on this type"),
+                             ty.span,
+                             "type")
+                        }
+                    };
+                    span_err.span_label(span, format!("{} parameter not allowed", kind))
+                            .emit();
+                    if err_for_lt && err_for_ty {
+                        break;
+                    }
                 }
-                for binding in &parameters.bindings {
+                for binding in &generic_args.bindings {
                     self.prohibit_projection(binding.span);
                     break;
                 }
@@ -1016,21 +1039,21 @@ pub fn def_to_ty(&self,
             Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) |
             Def::Union(did) | Def::TyForeign(did) => {
                 assert_eq!(opt_self_ty, None);
-                self.prohibit_type_params(path.segments.split_last().unwrap().1);
+                self.prohibit_generics(path.segments.split_last().unwrap().1);
                 self.ast_path_to_ty(span, did, path.segments.last().unwrap())
             }
             Def::Variant(did) if permit_variants => {
                 // Convert "variant type" as if it were a real type.
                 // The resulting `Ty` is type of the variant's enum for now.
                 assert_eq!(opt_self_ty, None);
-                self.prohibit_type_params(path.segments.split_last().unwrap().1);
+                self.prohibit_generics(path.segments.split_last().unwrap().1);
                 self.ast_path_to_ty(span,
                                     tcx.parent_def_id(did).unwrap(),
                                     path.segments.last().unwrap())
             }
             Def::TyParam(did) => {
                 assert_eq!(opt_self_ty, None);
-                self.prohibit_type_params(&path.segments);
+                self.prohibit_generics(&path.segments);
 
                 let node_id = tcx.hir.as_local_node_id(did).unwrap();
                 let item_id = tcx.hir.get_parent_node(node_id);
@@ -1043,18 +1066,18 @@ pub fn def_to_ty(&self,
                 // Self in impl (we know the concrete type).
 
                 assert_eq!(opt_self_ty, None);
-                self.prohibit_type_params(&path.segments);
+                self.prohibit_generics(&path.segments);
 
                 tcx.at(span).type_of(def_id)
             }
             Def::SelfTy(Some(_), None) => {
                 // Self in trait.
                 assert_eq!(opt_self_ty, None);
-                self.prohibit_type_params(&path.segments);
+                self.prohibit_generics(&path.segments);
                 tcx.mk_self_type()
             }
             Def::AssociatedTy(def_id) => {
-                self.prohibit_type_params(&path.segments[..path.segments.len()-2]);
+                self.prohibit_generics(&path.segments[..path.segments.len()-2]);
                 self.qpath_to_ty(span,
                                  opt_self_ty,
                                  def_id,
@@ -1063,7 +1086,7 @@ pub fn def_to_ty(&self,
             }
             Def::PrimTy(prim_ty) => {
                 assert_eq!(opt_self_ty, None);
-                self.prohibit_type_params(&path.segments);
+                self.prohibit_generics(&path.segments);
                 match prim_ty {
                     hir::TyBool => tcx.types.bool,
                     hir::TyChar => tcx.types.char,
index f0d7ca8ebf14f6c5ee29d6a15b5c1437fff3b57a..07e19c84a95073dff0b4734812dd885ea28667c8 100644 (file)
@@ -365,28 +365,27 @@ fn report_cast_to_unsized_type(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) {
     fn trivial_cast_lint(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) {
         let t_cast = self.cast_ty;
         let t_expr = self.expr_ty;
-        if t_cast.is_numeric() && t_expr.is_numeric() {
-            fcx.tcx.lint_node(
-                lint::builtin::TRIVIAL_NUMERIC_CASTS,
-                self.expr.id,
-                self.span,
-                &format!("trivial numeric cast: `{}` as `{}`. Cast can be \
-                          replaced by coercion, this might require type \
-                          ascription or a temporary variable",
-                         fcx.ty_to_string(t_expr),
-                         fcx.ty_to_string(t_cast)));
+        let type_asc_or = if fcx.tcx.features().type_ascription {
+            "type ascription or "
         } else {
-            fcx.tcx.lint_node(
-                lint::builtin::TRIVIAL_CASTS,
-                self.expr.id,
-                self.span,
-                &format!("trivial cast: `{}` as `{}`. Cast can be \
-                          replaced by coercion, this might require type \
-                          ascription or a temporary variable",
-                         fcx.ty_to_string(t_expr),
-                         fcx.ty_to_string(t_cast)));
-        }
-
+            ""
+        };
+        let (adjective, lint) = if t_cast.is_numeric() && t_expr.is_numeric() {
+            ("numeric ", lint::builtin::TRIVIAL_NUMERIC_CASTS)
+        } else {
+            ("", lint::builtin::TRIVIAL_CASTS)
+        };
+        let mut err = fcx.tcx.struct_span_lint_node(
+            lint,
+            self.expr.id,
+            self.span,
+            &format!("trivial {}cast: `{}` as `{}`",
+                     adjective,
+                     fcx.ty_to_string(t_expr),
+                     fcx.ty_to_string(t_cast)));
+        err.help(&format!("cast can be replaced by coercion; this might \
+                           require {}a temporary variable", type_asc_or));
+        err.emit();
     }
 
     pub fn check(mut self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) {
index 808c134e9944864f964cb85648ee0474fb0e67a0..5f8955612e10cb00614bf34c15aae479d6eab212 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use rustc::hir::{self, ImplItemKind, TraitItemKind};
+use rustc::hir::{self, GenericParamKind, ImplItemKind, TraitItemKind};
 use rustc::infer::{self, InferOk};
 use rustc::ty::{self, TyCtxt, GenericParamDefKind};
 use rustc::ty::util::ExplicitSelf;
@@ -728,11 +728,9 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let mut error_found = false;
     let impl_m_generics = tcx.generics_of(impl_m.def_id);
     let trait_m_generics = tcx.generics_of(trait_m.def_id);
-    let impl_m_type_params = impl_m_generics.params.iter().filter_map(|param| {
-        match param.kind {
-            GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)),
-            GenericParamDefKind::Lifetime => None,
-        }
+    let impl_m_type_params = impl_m_generics.params.iter().filter_map(|param| match param.kind {
+        GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)),
+        GenericParamDefKind::Lifetime => None,
     });
     let trait_m_type_params = trait_m_generics.params.iter().filter_map(|param| {
         match param.kind {
@@ -843,19 +841,19 @@ fn nested_visit_map<'this>(
                         }
                         let span = visitor.0?;
 
-                        let param = impl_m.generics.params.iter().filter_map(|param| {
-                            match param {
-                                hir::GenericParam::Type(param) => {
+                        let bounds = impl_m.generics.params.iter().find_map(|param| {
+                            match param.kind {
+                                GenericParamKind::Lifetime { .. } => None,
+                                GenericParamKind::Type { .. } => {
                                     if param.id == impl_node_id {
-                                        Some(param)
+                                        Some(&param.bounds)
                                     } else {
                                         None
                                     }
-                                },
-                                hir::GenericParam::Lifetime(..) => None,
+                                }
                             }
-                        }).next()?;
-                        let bounds = param.bounds.first()?.span().to(param.bounds.last()?.span());
+                        })?;
+                        let bounds = bounds.first()?.span().to(bounds.last()?.span());
                         let bounds = tcx
                             .sess
                             .codemap()
index f3a3c30fe5ad9ba09ac04903f3fd5ede60bb595f..36ce01bcd08b30cd266aa242a1c68fede31fae50 100644 (file)
@@ -12,6 +12,7 @@
 
 use astconv::AstConv;
 use check::{FnCtxt, PlaceOp, callee, Needs};
+use hir::GenericArg;
 use hir::def_id::DefId;
 use rustc::ty::subst::Substs;
 use rustc::traits;
@@ -59,7 +60,7 @@ pub fn confirm_method(
             "confirm(unadjusted_self_ty={:?}, pick={:?}, generic_args={:?})",
             unadjusted_self_ty,
             pick,
-            segment.parameters,
+            segment.args,
         );
 
         let mut confirm_cx = ConfirmContext::new(self, span, self_expr, call_expr);
@@ -316,36 +317,44 @@ fn instantiate_method_substs(
         let method_generics = self.tcx.generics_of(pick.item.def_id);
         let mut fn_segment = Some((segment, method_generics));
         let supress_mismatch = self.fcx.check_impl_trait(self.span, fn_segment);
-        self.fcx.check_path_parameter_count(self.span, &mut fn_segment, true, supress_mismatch);
+        self.fcx.check_generic_arg_count(self.span, &mut fn_segment, true, supress_mismatch);
 
         // Create subst for early-bound lifetime parameters, combining
         // parameters from the type and those from the method.
         assert_eq!(method_generics.parent_count, parent_substs.len());
-        let provided = &segment.parameters;
+        let provided = &segment.args;
         let own_counts = method_generics.own_counts();
         Substs::for_item(self.tcx, pick.item.def_id, |param, _| {
-            let i = param.index as usize;
+            let mut i = param.index as usize;
             if i < parent_substs.len() {
                 parent_substs[i]
             } else {
-                match param.kind {
-                    GenericParamDefKind::Lifetime => {
-                        if let Some(lifetime) = provided.as_ref().and_then(|p| {
-                            p.lifetimes.get(i - parent_substs.len())
-                        }) {
-                            return AstConv::ast_region_to_region(
-                                self.fcx, lifetime, Some(param)).into();
-                        }
-                    }
-                    GenericParamDefKind::Type {..} => {
-                        if let Some(ast_ty) = provided.as_ref().and_then(|p| {
-                            p.types.get(i - parent_substs.len() - own_counts.lifetimes)
-                        }) {
-                            return self.to_ty(ast_ty).into();
+                let (is_lt, is_ty) = match param.kind {
+                    GenericParamDefKind::Lifetime => (true, false),
+                    GenericParamDefKind::Type { .. } => (false, true),
+                };
+                provided.as_ref().and_then(|data| {
+                    for arg in &data.args {
+                        match arg {
+                            GenericArg::Lifetime(lt) if is_lt => {
+                                if i == parent_substs.len() {
+                                    return Some(AstConv::ast_region_to_region(
+                                        self.fcx, lt, Some(param)).into());
+                                }
+                                i -= 1;
+                            }
+                            GenericArg::Lifetime(_) => {}
+                            GenericArg::Type(ty) if is_ty => {
+                                if i == parent_substs.len() + own_counts.lifetimes {
+                                    return Some(self.to_ty(ty).into());
+                                }
+                                i -= 1;
+                            }
+                            GenericArg::Type(_) => {}
                         }
                     }
-                }
-                self.var_for_def(self.span, param)
+                    None
+                }).unwrap_or_else(|| self.var_for_def(self.span, param))
             }
         })
     }
index 90680b4156e7a825693bc6399eb9ebd360e2de21..546ce34fe12ae864a7e8300565513e796ab8f323 100644 (file)
@@ -25,7 +25,8 @@
 use syntax::ast;
 use syntax::util::lev_distance::find_best_match_for_name;
 use errors::DiagnosticBuilder;
-use syntax_pos::Span;
+use syntax_pos::{Span, FileName};
+
 
 use rustc::hir::def_id::LOCAL_CRATE;
 use rustc::hir;
@@ -187,7 +188,6 @@ pub fn report_method_error(&self,
                 out_of_scope_traits,
                 lev_candidate,
                 mode,
-                ..
             }) => {
                 let tcx = self.tcx;
 
@@ -264,13 +264,35 @@ pub fn report_method_error(&self,
                                         let span = tcx.hir.span(node_id);
                                         let snippet = tcx.sess.codemap().span_to_snippet(span)
                                             .unwrap();
-                                        err.span_suggestion(span,
-                                                            &format!("you must specify a type for \
-                                                                      this binding, like `{}`",
-                                                                     concrete_type),
-                                                            format!("{}: {}",
-                                                                    snippet,
-                                                                    concrete_type));
+                                        let filename = tcx.sess.codemap().span_to_filename(span);
+
+                                        let parent_node = self.tcx.hir.get(
+                                            self.tcx.hir.get_parent_node(node_id),
+                                        );
+                                        let msg = format!(
+                                            "you must specify a type for this binding, like `{}`",
+                                            concrete_type,
+                                        );
+
+                                        match (filename, parent_node) {
+                                            (FileName::Real(_), hir_map::NodeLocal(hir::Local {
+                                                source: hir::LocalSource::Normal,
+                                                ty,
+                                                ..
+                                            })) => {
+                                                err.span_suggestion(
+                                                    // account for `let x: _ = 42;`
+                                                    //                  ^^^^
+                                                    span.to(ty.as_ref().map(|ty| ty.span)
+                                                        .unwrap_or(span)),
+                                                    &msg,
+                                                    format!("{}: {}", snippet, concrete_type),
+                                                );
+                                            }
+                                            _ => {
+                                                err.span_label(span, msg);
+                                            }
+                                        }
                                     }
                                 }
                             }
index b70b61d191594f0baa9c8e2c6b4ee983a5b7de33..889073f6b4ca96a0ba5a9bfa67522c2176c73ce0 100644 (file)
@@ -85,6 +85,7 @@
 use self::TupleArgumentsFlag::*;
 
 use astconv::AstConv;
+use hir::GenericArg;
 use hir::def::Def;
 use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use std::slice;
@@ -1163,7 +1164,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
                     }
 
                     if let Node::NodeItem(item) = fcx.tcx.hir.get(fn_id) {
-                        if let Item_::ItemFn(_, _, _, _, ref generics, _) = item.node {
+                        if let Item_::ItemFn(_, _, ref generics, _) = item.node {
                             if !generics.params.is_empty() {
                                 fcx.tcx.sess.span_err(
                                     span,
@@ -1260,10 +1261,11 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item
       hir::ItemUnion(..) => {
         check_union(tcx, it.id, it.span);
       }
-      hir::ItemTy(_, ref generics) => {
+      hir::ItemTy(..) => {
         let def_id = tcx.hir.local_def_id(it.id);
         let pty_ty = tcx.type_of(def_id);
-        check_bounds_are_used(tcx, generics, pty_ty);
+        let generics = tcx.generics_of(def_id);
+        check_bounds_are_used(tcx, &generics, pty_ty);
       }
       hir::ItemForeignMod(ref m) => {
         check_abi(tcx, it.span, m.abi);
@@ -2329,7 +2331,7 @@ fn is_place_expr(&self, expr: &hir::Expr) -> bool {
             hir::ExprRepeat(..) |
             hir::ExprArray(..) |
             hir::ExprBreak(..) |
-            hir::ExprAgain(..) |
+            hir::ExprContinue(..) |
             hir::ExprRet(..) |
             hir::ExprWhile(..) |
             hir::ExprLoop(..) |
@@ -3609,579 +3611,586 @@ fn check_expr_kind(&self,
         let tcx = self.tcx;
         let id = expr.id;
         match expr.node {
-          hir::ExprBox(ref subexpr) => {
-            let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
-                match ty.sty {
-                    ty::TyAdt(def, _) if def.is_box()
-                        => Expectation::rvalue_hint(self, ty.boxed_ty()),
-                    _ => NoExpectation
-                }
-            });
-            let referent_ty = self.check_expr_with_expectation(subexpr, expected_inner);
-            tcx.mk_box(referent_ty)
-          }
-
-          hir::ExprLit(ref lit) => {
-            self.check_lit(&lit, expected)
-          }
-          hir::ExprBinary(op, ref lhs, ref rhs) => {
-            self.check_binop(expr, op, lhs, rhs)
-          }
-          hir::ExprAssignOp(op, ref lhs, ref rhs) => {
-            self.check_binop_assign(expr, op, lhs, rhs)
-          }
-          hir::ExprUnary(unop, ref oprnd) => {
-            let expected_inner = match unop {
-                hir::UnNot | hir::UnNeg => {
-                    expected
-                }
-                hir::UnDeref => {
-                    NoExpectation
-                }
-            };
-            let needs = match unop {
-                hir::UnDeref => needs,
-                _ => Needs::None
-            };
-            let mut oprnd_t = self.check_expr_with_expectation_and_needs(&oprnd,
-                                                                               expected_inner,
-                                                                               needs);
+            hir::ExprBox(ref subexpr) => {
+                let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
+                    match ty.sty {
+                        ty::TyAdt(def, _) if def.is_box()
+                            => Expectation::rvalue_hint(self, ty.boxed_ty()),
+                        _ => NoExpectation
+                    }
+                });
+                let referent_ty = self.check_expr_with_expectation(subexpr, expected_inner);
+                tcx.mk_box(referent_ty)
+            }
 
-            if !oprnd_t.references_error() {
-                oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
-                match unop {
+            hir::ExprLit(ref lit) => {
+                self.check_lit(&lit, expected)
+            }
+            hir::ExprBinary(op, ref lhs, ref rhs) => {
+                self.check_binop(expr, op, lhs, rhs)
+            }
+            hir::ExprAssignOp(op, ref lhs, ref rhs) => {
+                self.check_binop_assign(expr, op, lhs, rhs)
+            }
+            hir::ExprUnary(unop, ref oprnd) => {
+                let expected_inner = match unop {
+                    hir::UnNot | hir::UnNeg => {
+                        expected
+                    }
                     hir::UnDeref => {
-                        if let Some(mt) = oprnd_t.builtin_deref(true) {
-                            oprnd_t = mt.ty;
-                        } else if let Some(ok) = self.try_overloaded_deref(
-                                expr.span, oprnd_t, needs) {
-                            let method = self.register_infer_ok_obligations(ok);
-                            if let ty::TyRef(region, _, mutbl) = method.sig.inputs()[0].sty {
-                                let mutbl = match mutbl {
-                                    hir::MutImmutable => AutoBorrowMutability::Immutable,
-                                    hir::MutMutable => AutoBorrowMutability::Mutable {
-                                        // (It shouldn't actually matter for unary ops whether
-                                        // we enable two-phase borrows or not, since a unary
-                                        // op has no additional operands.)
-                                        allow_two_phase_borrow: AllowTwoPhase::No,
-                                    }
-                                };
-                                self.apply_adjustments(oprnd, vec![Adjustment {
-                                    kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
-                                    target: method.sig.inputs()[0]
-                                }]);
+                        NoExpectation
+                    }
+                };
+                let needs = match unop {
+                    hir::UnDeref => needs,
+                    _ => Needs::None
+                };
+                let mut oprnd_t = self.check_expr_with_expectation_and_needs(&oprnd,
+                                                                                    expected_inner,
+                                                                                    needs);
+
+                if !oprnd_t.references_error() {
+                    oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
+                    match unop {
+                        hir::UnDeref => {
+                            if let Some(mt) = oprnd_t.builtin_deref(true) {
+                                oprnd_t = mt.ty;
+                            } else if let Some(ok) = self.try_overloaded_deref(
+                                    expr.span, oprnd_t, needs) {
+                                let method = self.register_infer_ok_obligations(ok);
+                                if let ty::TyRef(region, _, mutbl) = method.sig.inputs()[0].sty {
+                                    let mutbl = match mutbl {
+                                        hir::MutImmutable => AutoBorrowMutability::Immutable,
+                                        hir::MutMutable => AutoBorrowMutability::Mutable {
+                                            // (It shouldn't actually matter for unary ops whether
+                                            // we enable two-phase borrows or not, since a unary
+                                            // op has no additional operands.)
+                                            allow_two_phase_borrow: AllowTwoPhase::No,
+                                        }
+                                    };
+                                    self.apply_adjustments(oprnd, vec![Adjustment {
+                                        kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
+                                        target: method.sig.inputs()[0]
+                                    }]);
+                                }
+                                oprnd_t = self.make_overloaded_place_return_type(method).ty;
+                                self.write_method_call(expr.hir_id, method);
+                            } else {
+                                type_error_struct!(tcx.sess, expr.span, oprnd_t, E0614,
+                                                    "type `{}` cannot be dereferenced",
+                                                    oprnd_t).emit();
+                                oprnd_t = tcx.types.err;
                             }
-                            oprnd_t = self.make_overloaded_place_return_type(method).ty;
-                            self.write_method_call(expr.hir_id, method);
-                        } else {
-                            type_error_struct!(tcx.sess, expr.span, oprnd_t, E0614,
-                                               "type `{}` cannot be dereferenced",
-                                               oprnd_t).emit();
-                            oprnd_t = tcx.types.err;
                         }
-                    }
-                    hir::UnNot => {
-                        let result = self.check_user_unop(expr, oprnd_t, unop);
-                        // If it's builtin, we can reuse the type, this helps inference.
-                        if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
-                            oprnd_t = result;
+                        hir::UnNot => {
+                            let result = self.check_user_unop(expr, oprnd_t, unop);
+                            // If it's builtin, we can reuse the type, this helps inference.
+                            if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
+                                oprnd_t = result;
+                            }
+                        }
+                        hir::UnNeg => {
+                            let result = self.check_user_unop(expr, oprnd_t, unop);
+                            // If it's builtin, we can reuse the type, this helps inference.
+                            if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
+                                oprnd_t = result;
+                            }
                         }
                     }
-                    hir::UnNeg => {
-                        let result = self.check_user_unop(expr, oprnd_t, unop);
-                        // If it's builtin, we can reuse the type, this helps inference.
-                        if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
-                            oprnd_t = result;
+                }
+                oprnd_t
+            }
+            hir::ExprAddrOf(mutbl, ref oprnd) => {
+                let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
+                    match ty.sty {
+                        ty::TyRef(_, ty, _) | ty::TyRawPtr(ty::TypeAndMut { ty, .. }) => {
+                            if self.is_place_expr(&oprnd) {
+                                // Places may legitimately have unsized types.
+                                // For example, dereferences of a fat pointer and
+                                // the last field of a struct can be unsized.
+                                ExpectHasType(ty)
+                            } else {
+                                Expectation::rvalue_hint(self, ty)
+                            }
                         }
+                        _ => NoExpectation
                     }
+                });
+                let needs = Needs::maybe_mut_place(mutbl);
+                let ty = self.check_expr_with_expectation_and_needs(&oprnd, hint, needs);
+
+                let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
+                if tm.ty.references_error() {
+                    tcx.types.err
+                } else {
+                    // Note: at this point, we cannot say what the best lifetime
+                    // is to use for resulting pointer.  We want to use the
+                    // shortest lifetime possible so as to avoid spurious borrowck
+                    // errors.  Moreover, the longest lifetime will depend on the
+                    // precise details of the value whose address is being taken
+                    // (and how long it is valid), which we don't know yet until type
+                    // inference is complete.
+                    //
+                    // Therefore, here we simply generate a region variable.  The
+                    // region inferencer will then select the ultimate value.
+                    // Finally, borrowck is charged with guaranteeing that the
+                    // value whose address was taken can actually be made to live
+                    // as long as it needs to live.
+                    let region = self.next_region_var(infer::AddrOfRegion(expr.span));
+                    tcx.mk_ref(region, tm)
                 }
             }
-            oprnd_t
-          }
-          hir::ExprAddrOf(mutbl, ref oprnd) => {
-            let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
-                match ty.sty {
-                    ty::TyRef(_, ty, _) | ty::TyRawPtr(ty::TypeAndMut { ty, .. }) => {
-                        if self.is_place_expr(&oprnd) {
-                            // Places may legitimately have unsized types.
-                            // For example, dereferences of a fat pointer and
-                            // the last field of a struct can be unsized.
-                            ExpectHasType(ty)
+            hir::ExprPath(ref qpath) => {
+                let (def, opt_ty, segs) = self.resolve_ty_and_def_ufcs(qpath, expr.id, expr.span);
+                let ty = if def != Def::Err {
+                    self.instantiate_value_path(segs, opt_ty, def, expr.span, id)
+                } else {
+                    self.set_tainted_by_errors();
+                    tcx.types.err
+                };
+
+                // We always require that the type provided as the value for
+                // a type parameter outlives the moment of instantiation.
+                let substs = self.tables.borrow().node_substs(expr.hir_id);
+                self.add_wf_bounds(substs, expr);
+
+                ty
+            }
+            hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
+                for output in outputs {
+                    self.check_expr(output);
+                }
+                for input in inputs {
+                    self.check_expr(input);
+                }
+                tcx.mk_nil()
+            }
+            hir::ExprBreak(destination, ref expr_opt) => {
+                if let Ok(target_id) = destination.target_id {
+                    let (e_ty, cause);
+                    if let Some(ref e) = *expr_opt {
+                        // If this is a break with a value, we need to type-check
+                        // the expression. Get an expected type from the loop context.
+                        let opt_coerce_to = {
+                            let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
+                            enclosing_breakables.find_breakable(target_id)
+                                                .coerce
+                                                .as_ref()
+                                                .map(|coerce| coerce.expected_ty())
+                        };
+
+                        // If the loop context is not a `loop { }`, then break with
+                        // a value is illegal, and `opt_coerce_to` will be `None`.
+                        // Just set expectation to error in that case.
+                        let coerce_to = opt_coerce_to.unwrap_or(tcx.types.err);
+
+                        // Recurse without `enclosing_breakables` borrowed.
+                        e_ty = self.check_expr_with_hint(e, coerce_to);
+                        cause = self.misc(e.span);
+                    } else {
+                        // Otherwise, this is a break *without* a value. That's
+                        // always legal, and is equivalent to `break ()`.
+                        e_ty = tcx.mk_nil();
+                        cause = self.misc(expr.span);
+                    }
+
+                    // Now that we have type-checked `expr_opt`, borrow
+                    // the `enclosing_loops` field and let's coerce the
+                    // type of `expr_opt` into what is expected.
+                    let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
+                    let ctxt = enclosing_breakables.find_breakable(target_id);
+                    if let Some(ref mut coerce) = ctxt.coerce {
+                        if let Some(ref e) = *expr_opt {
+                            coerce.coerce(self, &cause, e, e_ty);
                         } else {
-                            Expectation::rvalue_hint(self, ty)
+                            assert!(e_ty.is_nil());
+                            coerce.coerce_forced_unit(self, &cause, &mut |_| (), true);
                         }
+                    } else {
+                        // If `ctxt.coerce` is `None`, we can just ignore
+                        // the type of the expresison.  This is because
+                        // either this was a break *without* a value, in
+                        // which case it is always a legal type (`()`), or
+                        // else an error would have been flagged by the
+                        // `loops` pass for using break with an expression
+                        // where you are not supposed to.
+                        assert!(expr_opt.is_none() || self.tcx.sess.err_count() > 0);
                     }
-                    _ => NoExpectation
+
+                    ctxt.may_break = true;
+
+                    // the type of a `break` is always `!`, since it diverges
+                    tcx.types.never
+                } else {
+                    // Otherwise, we failed to find the enclosing loop;
+                    // this can only happen if the `break` was not
+                    // inside a loop at all, which is caught by the
+                    // loop-checking pass.
+                    assert!(self.tcx.sess.err_count() > 0);
+
+                    // We still need to assign a type to the inner expression to
+                    // prevent the ICE in #43162.
+                    if let Some(ref e) = *expr_opt {
+                        self.check_expr_with_hint(e, tcx.types.err);
+
+                        // ... except when we try to 'break rust;'.
+                        // ICE this expression in particular (see #43162).
+                        if let hir::ExprPath(hir::QPath::Resolved(_, ref path)) = e.node {
+                            if path.segments.len() == 1 && path.segments[0].name == "rust" {
+                                fatally_break_rust(self.tcx.sess);
+                            }
+                        }
+                    }
+                    // There was an error, make typecheck fail
+                    tcx.types.err
                 }
-            });
-            let needs = Needs::maybe_mut_place(mutbl);
-            let ty = self.check_expr_with_expectation_and_needs(&oprnd, hint, needs);
 
-            let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
-            if tm.ty.references_error() {
-                tcx.types.err
-            } else {
-                // Note: at this point, we cannot say what the best lifetime
-                // is to use for resulting pointer.  We want to use the
-                // shortest lifetime possible so as to avoid spurious borrowck
-                // errors.  Moreover, the longest lifetime will depend on the
-                // precise details of the value whose address is being taken
-                // (and how long it is valid), which we don't know yet until type
-                // inference is complete.
-                //
-                // Therefore, here we simply generate a region variable.  The
-                // region inferencer will then select the ultimate value.
-                // Finally, borrowck is charged with guaranteeing that the
-                // value whose address was taken can actually be made to live
-                // as long as it needs to live.
-                let region = self.next_region_var(infer::AddrOfRegion(expr.span));
-                tcx.mk_ref(region, tm)
             }
-          }
-          hir::ExprPath(ref qpath) => {
-              let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath,
-                                                                         expr.id, expr.span);
-              let ty = if def != Def::Err {
-                  self.instantiate_value_path(segments, opt_ty, def, expr.span, id)
-              } else {
-                  self.set_tainted_by_errors();
-                  tcx.types.err
-              };
-
-              // We always require that the type provided as the value for
-              // a type parameter outlives the moment of instantiation.
-              let substs = self.tables.borrow().node_substs(expr.hir_id);
-              self.add_wf_bounds(substs, expr);
-
-              ty
-          }
-          hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
-              for output in outputs {
-                  self.check_expr(output);
-              }
-              for input in inputs {
-                  self.check_expr(input);
-              }
-              tcx.mk_nil()
-          }
-          hir::ExprBreak(destination, ref expr_opt) => {
-              if let Ok(target_id) = destination.target_id {
-                  let (e_ty, cause);
-                  if let Some(ref e) = *expr_opt {
-                      // If this is a break with a value, we need to type-check
-                      // the expression. Get an expected type from the loop context.
-                      let opt_coerce_to = {
-                          let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
-                          enclosing_breakables.find_breakable(target_id)
-                                              .coerce
-                                              .as_ref()
-                                              .map(|coerce| coerce.expected_ty())
-                      };
-
-                      // If the loop context is not a `loop { }`, then break with
-                      // a value is illegal, and `opt_coerce_to` will be `None`.
-                      // Just set expectation to error in that case.
-                      let coerce_to = opt_coerce_to.unwrap_or(tcx.types.err);
-
-                      // Recurse without `enclosing_breakables` borrowed.
-                      e_ty = self.check_expr_with_hint(e, coerce_to);
-                      cause = self.misc(e.span);
-                  } else {
-                      // Otherwise, this is a break *without* a value. That's
-                      // always legal, and is equivalent to `break ()`.
-                      e_ty = tcx.mk_nil();
-                      cause = self.misc(expr.span);
-                  }
-
-                  // Now that we have type-checked `expr_opt`, borrow
-                  // the `enclosing_loops` field and let's coerce the
-                  // type of `expr_opt` into what is expected.
-                  let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
-                  let ctxt = enclosing_breakables.find_breakable(target_id);
-                  if let Some(ref mut coerce) = ctxt.coerce {
-                      if let Some(ref e) = *expr_opt {
-                          coerce.coerce(self, &cause, e, e_ty);
-                      } else {
-                          assert!(e_ty.is_nil());
-                          coerce.coerce_forced_unit(self, &cause, &mut |_| (), true);
-                      }
-                  } else {
-                      // If `ctxt.coerce` is `None`, we can just ignore
-                      // the type of the expresison.  This is because
-                      // either this was a break *without* a value, in
-                      // which case it is always a legal type (`()`), or
-                      // else an error would have been flagged by the
-                      // `loops` pass for using break with an expression
-                      // where you are not supposed to.
-                      assert!(expr_opt.is_none() || self.tcx.sess.err_count() > 0);
-                  }
-
-                  ctxt.may_break = true;
-
-                  // the type of a `break` is always `!`, since it diverges
-                  tcx.types.never
-              } else {
-                  // Otherwise, we failed to find the enclosing loop;
-                  // this can only happen if the `break` was not
-                  // inside a loop at all, which is caught by the
-                  // loop-checking pass.
-                  assert!(self.tcx.sess.err_count() > 0);
-
-                  // We still need to assign a type to the inner expression to
-                  // prevent the ICE in #43162.
-                  if let Some(ref e) = *expr_opt {
-                      self.check_expr_with_hint(e, tcx.types.err);
-
-                      // ... except when we try to 'break rust;'.
-                      // ICE this expression in particular (see #43162).
-                      if let hir::ExprPath(hir::QPath::Resolved(_, ref path)) = e.node {
-                          if path.segments.len() == 1 && path.segments[0].name == "rust" {
-                              fatally_break_rust(self.tcx.sess);
-                          }
-                      }
-                  }
-                  // There was an error, make typecheck fail
-                  tcx.types.err
-              }
-
-          }
-          hir::ExprAgain(_) => { tcx.types.never }
-          hir::ExprRet(ref expr_opt) => {
-            if self.ret_coercion.is_none() {
-                struct_span_err!(self.tcx.sess, expr.span, E0572,
-                                 "return statement outside of function body").emit();
-            } else if let Some(ref e) = *expr_opt {
-                self.check_return_expr(e);
-            } else {
-                let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
-                let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
-                coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
+            hir::ExprContinue(destination) => {
+                if let Ok(_) = destination.target_id {
+                    tcx.types.never
+                } else {
+                    // There was an error, make typecheck fail
+                    tcx.types.err
+                }
             }
-            tcx.types.never
-          }
-          hir::ExprAssign(ref lhs, ref rhs) => {
-            let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
+            hir::ExprRet(ref expr_opt) => {
+                if self.ret_coercion.is_none() {
+                    struct_span_err!(self.tcx.sess, expr.span, E0572,
+                                        "return statement outside of function body").emit();
+                } else if let Some(ref e) = *expr_opt {
+                    self.check_return_expr(e);
+                } else {
+                    let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
+                    let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
+                    coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
+                }
+                tcx.types.never
+            }
+            hir::ExprAssign(ref lhs, ref rhs) => {
+                let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
 
-            let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
+                let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
 
-            match expected {
-                ExpectIfCondition => {
-                    self.tcx.sess.delay_span_bug(lhs.span, "invalid lhs expression in if;\
-                                                            expected error elsehwere");
-                }
-                _ => {
-                    // Only check this if not in an `if` condition, as the
-                    // mistyped comparison help is more appropriate.
-                    if !self.is_place_expr(&lhs) {
-                        struct_span_err!(self.tcx.sess, expr.span, E0070,
-                                         "invalid left-hand side expression")
-                            .span_label(expr.span, "left-hand of expression not valid")
-                            .emit();
+                match expected {
+                    ExpectIfCondition => {
+                        self.tcx.sess.delay_span_bug(lhs.span, "invalid lhs expression in if;\
+                                                                expected error elsehwere");
+                    }
+                    _ => {
+                        // Only check this if not in an `if` condition, as the
+                        // mistyped comparison help is more appropriate.
+                        if !self.is_place_expr(&lhs) {
+                            struct_span_err!(self.tcx.sess, expr.span, E0070,
+                                                "invalid left-hand side expression")
+                                .span_label(expr.span, "left-hand of expression not valid")
+                                .emit();
+                        }
                     }
                 }
+
+                self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
+
+                if lhs_ty.references_error() || rhs_ty.references_error() {
+                    tcx.types.err
+                } else {
+                    tcx.mk_nil()
+                }
+            }
+            hir::ExprIf(ref cond, ref then_expr, ref opt_else_expr) => {
+                self.check_then_else(&cond, then_expr, opt_else_expr.as_ref().map(|e| &**e),
+                                    expr.span, expected)
             }
+            hir::ExprWhile(ref cond, ref body, _) => {
+                let ctxt = BreakableCtxt {
+                    // cannot use break with a value from a while loop
+                    coerce: None,
+                    may_break: false,  // Will get updated if/when we find a `break`.
+                };
 
-            self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
+                let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
+                    self.check_expr_has_type_or_error(&cond, tcx.types.bool);
+                    let cond_diverging = self.diverges.get();
+                    self.check_block_no_value(&body);
 
-            if lhs_ty.references_error() || rhs_ty.references_error() {
-                tcx.types.err
-            } else {
-                tcx.mk_nil()
+                    // We may never reach the body so it diverging means nothing.
+                    self.diverges.set(cond_diverging);
+                });
+
+                if ctxt.may_break {
+                    // No way to know whether it's diverging because
+                    // of a `break` or an outer `break` or `return`.
+                    self.diverges.set(Diverges::Maybe);
+                }
+
+                self.tcx.mk_nil()
             }
-          }
-          hir::ExprIf(ref cond, ref then_expr, ref opt_else_expr) => {
-              self.check_then_else(&cond, then_expr, opt_else_expr.as_ref().map(|e| &**e),
-                                   expr.span, expected)
-          }
-          hir::ExprWhile(ref cond, ref body, _) => {
-              let ctxt = BreakableCtxt {
-                  // cannot use break with a value from a while loop
-                  coerce: None,
-                  may_break: false,  // Will get updated if/when we find a `break`.
-              };
-
-              let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
-                  self.check_expr_has_type_or_error(&cond, tcx.types.bool);
-                  let cond_diverging = self.diverges.get();
-                  self.check_block_no_value(&body);
-
-                  // We may never reach the body so it diverging means nothing.
-                  self.diverges.set(cond_diverging);
-              });
-
-              if ctxt.may_break {
-                  // No way to know whether it's diverging because
-                  // of a `break` or an outer `break` or `return`.
-                  self.diverges.set(Diverges::Maybe);
-              }
-
-              self.tcx.mk_nil()
-          }
-          hir::ExprLoop(ref body, _, source) => {
-              let coerce = match source {
-                  // you can only use break with a value from a normal `loop { }`
-                  hir::LoopSource::Loop => {
-                      let coerce_to = expected.coercion_target_type(self, body.span);
-                      Some(CoerceMany::new(coerce_to))
-                  }
-
-                  hir::LoopSource::WhileLet |
-                  hir::LoopSource::ForLoop => {
-                      None
-                  }
-              };
-
-              let ctxt = BreakableCtxt {
-                  coerce,
-                  may_break: false, // Will get updated if/when we find a `break`.
-              };
-
-              let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
-                  self.check_block_no_value(&body);
-              });
-
-              if ctxt.may_break {
-                  // No way to know whether it's diverging because
-                  // of a `break` or an outer `break` or `return`.
-                  self.diverges.set(Diverges::Maybe);
-              }
-
-              // If we permit break with a value, then result type is
-              // the LUB of the breaks (possibly ! if none); else, it
-              // is nil. This makes sense because infinite loops
-              // (which would have type !) are only possible iff we
-              // permit break with a value [1].
-              assert!(ctxt.coerce.is_some() || ctxt.may_break); // [1]
-              ctxt.coerce.map(|c| c.complete(self)).unwrap_or(self.tcx.mk_nil())
-          }
-          hir::ExprMatch(ref discrim, ref arms, match_src) => {
-            self.check_match(expr, &discrim, arms, expected, match_src)
-          }
-          hir::ExprClosure(capture, ref decl, body_id, _, gen) => {
-              self.check_expr_closure(expr, capture, &decl, body_id, gen, expected)
-          }
-          hir::ExprBlock(ref body, _) => {
-            self.check_block_with_expected(&body, expected)
-          }
-          hir::ExprCall(ref callee, ref args) => {
-              self.check_call(expr, &callee, args, expected)
-          }
-          hir::ExprMethodCall(ref segment, span, ref args) => {
-              self.check_method_call(expr, segment, span, args, expected, needs)
-          }
-          hir::ExprCast(ref e, ref t) => {
-            // Find the type of `e`. Supply hints based on the type we are casting to,
-            // if appropriate.
-            let t_cast = self.to_ty(t);
-            let t_cast = self.resolve_type_vars_if_possible(&t_cast);
-            let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
-            let t_cast = self.resolve_type_vars_if_possible(&t_cast);
-
-            // Eagerly check for some obvious errors.
-            if t_expr.references_error() || t_cast.references_error() {
-                tcx.types.err
-            } else {
-                // Defer other checks until we're done type checking.
-                let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
-                match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
-                    Ok(cast_check) => {
-                        deferred_cast_checks.push(cast_check);
-                        t_cast
+            hir::ExprLoop(ref body, _, source) => {
+                let coerce = match source {
+                    // you can only use break with a value from a normal `loop { }`
+                    hir::LoopSource::Loop => {
+                        let coerce_to = expected.coercion_target_type(self, body.span);
+                        Some(CoerceMany::new(coerce_to))
                     }
-                    Err(ErrorReported) => {
-                        tcx.types.err
+
+                    hir::LoopSource::WhileLet |
+                    hir::LoopSource::ForLoop => {
+                        None
                     }
+                };
+
+                let ctxt = BreakableCtxt {
+                    coerce,
+                    may_break: false, // Will get updated if/when we find a `break`.
+                };
+
+                let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
+                    self.check_block_no_value(&body);
+                });
+
+                if ctxt.may_break {
+                    // No way to know whether it's diverging because
+                    // of a `break` or an outer `break` or `return`.
+                    self.diverges.set(Diverges::Maybe);
                 }
-            }
-          }
-          hir::ExprType(ref e, ref t) => {
-            let typ = self.to_ty(&t);
-            self.check_expr_eq_type(&e, typ);
-            typ
-          }
-          hir::ExprArray(ref args) => {
-              let uty = expected.to_option(self).and_then(|uty| {
-                  match uty.sty {
-                      ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
-                      _ => None
-                  }
-              });
-
-              let element_ty = if !args.is_empty() {
-                  let coerce_to = uty.unwrap_or_else(
-                      || self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span)));
-                  let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
-                  assert_eq!(self.diverges.get(), Diverges::Maybe);
-                  for e in args {
-                      let e_ty = self.check_expr_with_hint(e, coerce_to);
-                      let cause = self.misc(e.span);
-                      coerce.coerce(self, &cause, e, e_ty);
-                  }
-                  coerce.complete(self)
-              } else {
-                  self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span))
-              };
-              tcx.mk_array(element_ty, args.len() as u64)
-          }
-          hir::ExprRepeat(ref element, ref count) => {
-            let count_def_id = tcx.hir.local_def_id(count.id);
-            let param_env = ty::ParamEnv::empty();
-            let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id);
-            let instance = ty::Instance::resolve(
-                tcx.global_tcx(),
-                param_env,
-                count_def_id,
-                substs,
-            ).unwrap();
-            let global_id = GlobalId {
-                instance,
-                promoted: None
-            };
-            let count = tcx.const_eval(param_env.and(global_id));
 
-            if let Err(ref err) = count {
-                err.report_as_error(
-                    tcx.at(tcx.def_span(count_def_id)),
-                    "could not evaluate repeat length",
-                );
+                // If we permit break with a value, then result type is
+                // the LUB of the breaks (possibly ! if none); else, it
+                // is nil. This makes sense because infinite loops
+                // (which would have type !) are only possible iff we
+                // permit break with a value [1].
+                assert!(ctxt.coerce.is_some() || ctxt.may_break); // [1]
+                ctxt.coerce.map(|c| c.complete(self)).unwrap_or(self.tcx.mk_nil())
             }
-
-            let uty = match expected {
-                ExpectHasType(uty) => {
+            hir::ExprMatch(ref discrim, ref arms, match_src) => {
+                self.check_match(expr, &discrim, arms, expected, match_src)
+            }
+            hir::ExprClosure(capture, ref decl, body_id, _, gen) => {
+                self.check_expr_closure(expr, capture, &decl, body_id, gen, expected)
+            }
+            hir::ExprBlock(ref body, _) => {
+                self.check_block_with_expected(&body, expected)
+            }
+            hir::ExprCall(ref callee, ref args) => {
+                self.check_call(expr, &callee, args, expected)
+            }
+            hir::ExprMethodCall(ref segment, span, ref args) => {
+                self.check_method_call(expr, segment, span, args, expected, needs)
+            }
+            hir::ExprCast(ref e, ref t) => {
+                // Find the type of `e`. Supply hints based on the type we are casting to,
+                // if appropriate.
+                let t_cast = self.to_ty(t);
+                let t_cast = self.resolve_type_vars_if_possible(&t_cast);
+                let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
+                let t_cast = self.resolve_type_vars_if_possible(&t_cast);
+
+                // Eagerly check for some obvious errors.
+                if t_expr.references_error() || t_cast.references_error() {
+                    tcx.types.err
+                } else {
+                    // Defer other checks until we're done type checking.
+                    let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
+                    match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
+                        Ok(cast_check) => {
+                            deferred_cast_checks.push(cast_check);
+                            t_cast
+                        }
+                        Err(ErrorReported) => {
+                            tcx.types.err
+                        }
+                    }
+                }
+            }
+            hir::ExprType(ref e, ref t) => {
+                let ty = self.to_ty(&t);
+                self.check_expr_eq_type(&e, ty);
+                ty
+            }
+            hir::ExprArray(ref args) => {
+                let uty = expected.to_option(self).and_then(|uty| {
                     match uty.sty {
                         ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
                         _ => None
                     }
-                }
-                _ => None
-            };
+                });
 
-            let (element_ty, t) = match uty {
-                Some(uty) => {
-                    self.check_expr_coercable_to_type(&element, uty);
-                    (uty, uty)
-                }
-                None => {
-                    let t: Ty = self.next_ty_var(TypeVariableOrigin::MiscVariable(element.span));
-                    let element_ty = self.check_expr_has_type_or_error(&element, t);
-                    (element_ty, t)
-                }
-            };
+                let element_ty = if !args.is_empty() {
+                    let coerce_to = uty.unwrap_or_else(
+                        || self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span)));
+                    let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
+                    assert_eq!(self.diverges.get(), Diverges::Maybe);
+                    for e in args {
+                        let e_ty = self.check_expr_with_hint(e, coerce_to);
+                        let cause = self.misc(e.span);
+                        coerce.coerce(self, &cause, e, e_ty);
+                    }
+                    coerce.complete(self)
+                } else {
+                    self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span))
+                };
+                tcx.mk_array(element_ty, args.len() as u64)
+            }
+            hir::ExprRepeat(ref element, ref count) => {
+                let count_def_id = tcx.hir.local_def_id(count.id);
+                let param_env = ty::ParamEnv::empty();
+                let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id);
+                let instance = ty::Instance::resolve(
+                    tcx.global_tcx(),
+                    param_env,
+                    count_def_id,
+                    substs,
+                ).unwrap();
+                let global_id = GlobalId {
+                    instance,
+                    promoted: None
+                };
+                let count = tcx.const_eval(param_env.and(global_id));
 
-            if let Ok(count) = count {
-                let zero_or_one = count.assert_usize(tcx).map_or(false, |count| count <= 1);
-                if !zero_or_one {
-                    // For [foo, ..n] where n > 1, `foo` must have
-                    // Copy type:
-                    let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
-                    self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
+                if let Err(ref err) = count {
+                    err.report_as_error(
+                        tcx.at(tcx.def_span(count_def_id)),
+                        "could not evaluate repeat length",
+                    );
                 }
-            }
 
-            if element_ty.references_error() {
-                tcx.types.err
-            } else if let Ok(count) = count {
-                tcx.mk_ty(ty::TyArray(t, count))
-            } else {
-                tcx.types.err
-            }
-          }
-          hir::ExprTup(ref elts) => {
-            let flds = expected.only_has_type(self).and_then(|ty| {
-                let ty = self.resolve_type_vars_with_obligations(ty);
-                match ty.sty {
-                    ty::TyTuple(ref flds) => Some(&flds[..]),
+                let uty = match expected {
+                    ExpectHasType(uty) => {
+                        match uty.sty {
+                            ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
+                            _ => None
+                        }
+                    }
                     _ => None
-                }
-            });
+                };
 
-            let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
-                let t = match flds {
-                    Some(ref fs) if i < fs.len() => {
-                        let ety = fs[i];
-                        self.check_expr_coercable_to_type(&e, ety);
-                        ety
+                let (element_ty, t) = match uty {
+                    Some(uty) => {
+                        self.check_expr_coercable_to_type(&element, uty);
+                        (uty, uty)
                     }
-                    _ => {
-                        self.check_expr_with_expectation(&e, NoExpectation)
+                    None => {
+                        let ty = self.next_ty_var(TypeVariableOrigin::MiscVariable(element.span));
+                        let element_ty = self.check_expr_has_type_or_error(&element, ty);
+                        (element_ty, ty)
                     }
                 };
-                t
-            });
-            let tuple = tcx.mk_tup(elt_ts_iter);
-            if tuple.references_error() {
-                tcx.types.err
-            } else {
-                self.require_type_is_sized(tuple, expr.span, traits::TupleInitializerSized);
-                tuple
+
+                if let Ok(count) = count {
+                    let zero_or_one = count.assert_usize(tcx).map_or(false, |count| count <= 1);
+                    if !zero_or_one {
+                        // For [foo, ..n] where n > 1, `foo` must have
+                        // Copy type:
+                        let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
+                        self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
+                    }
+                }
+
+                if element_ty.references_error() {
+                    tcx.types.err
+                } else if let Ok(count) = count {
+                    tcx.mk_ty(ty::TyArray(t, count))
+                } else {
+                    tcx.types.err
+                }
             }
-          }
-          hir::ExprStruct(ref qpath, ref fields, ref base_expr) => {
-            self.check_expr_struct(expr, expected, qpath, fields, base_expr)
-          }
-          hir::ExprField(ref base, field) => {
-            self.check_field(expr, needs, &base, field)
-          }
-          hir::ExprIndex(ref base, ref idx) => {
-              let base_t = self.check_expr_with_needs(&base, needs);
-              let idx_t = self.check_expr(&idx);
-
-              if base_t.references_error() {
-                  base_t
-              } else if idx_t.references_error() {
-                  idx_t
-              } else {
-                  let base_t = self.structurally_resolved_type(base.span, base_t);
-                  match self.lookup_indexing(expr, base, base_t, idx_t, needs) {
-                      Some((index_ty, element_ty)) => {
-                          // two-phase not needed because index_ty is never mutable
-                          self.demand_coerce(idx, idx_t, index_ty, AllowTwoPhase::No);
-                          element_ty
-                      }
-                      None => {
-                          let mut err = type_error_struct!(tcx.sess, expr.span, base_t, E0608,
-                                                           "cannot index into a value of type `{}`",
-                                                           base_t);
-                          // Try to give some advice about indexing tuples.
-                          if let ty::TyTuple(..) = base_t.sty {
-                              let mut needs_note = true;
-                              // If the index is an integer, we can show the actual
-                              // fixed expression:
-                              if let hir::ExprLit(ref lit) = idx.node {
-                                  if let ast::LitKind::Int(i,
+            hir::ExprTup(ref elts) => {
+                let flds = expected.only_has_type(self).and_then(|ty| {
+                    let ty = self.resolve_type_vars_with_obligations(ty);
+                    match ty.sty {
+                        ty::TyTuple(ref flds) => Some(&flds[..]),
+                        _ => None
+                    }
+                });
+
+                let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
+                    let t = match flds {
+                        Some(ref fs) if i < fs.len() => {
+                            let ety = fs[i];
+                            self.check_expr_coercable_to_type(&e, ety);
+                            ety
+                        }
+                        _ => {
+                            self.check_expr_with_expectation(&e, NoExpectation)
+                        }
+                    };
+                    t
+                });
+                let tuple = tcx.mk_tup(elt_ts_iter);
+                if tuple.references_error() {
+                    tcx.types.err
+                } else {
+                    self.require_type_is_sized(tuple, expr.span, traits::TupleInitializerSized);
+                    tuple
+                }
+            }
+            hir::ExprStruct(ref qpath, ref fields, ref base_expr) => {
+                self.check_expr_struct(expr, expected, qpath, fields, base_expr)
+            }
+            hir::ExprField(ref base, field) => {
+                self.check_field(expr, needs, &base, field)
+            }
+            hir::ExprIndex(ref base, ref idx) => {
+                let base_t = self.check_expr_with_needs(&base, needs);
+                let idx_t = self.check_expr(&idx);
+
+                if base_t.references_error() {
+                    base_t
+                } else if idx_t.references_error() {
+                    idx_t
+                } else {
+                    let base_t = self.structurally_resolved_type(base.span, base_t);
+                    match self.lookup_indexing(expr, base, base_t, idx_t, needs) {
+                        Some((index_ty, element_ty)) => {
+                            // two-phase not needed because index_ty is never mutable
+                            self.demand_coerce(idx, idx_t, index_ty, AllowTwoPhase::No);
+                            element_ty
+                        }
+                        None => {
+                            let mut err =
+                                type_error_struct!(tcx.sess, expr.span, base_t, E0608,
+                                                   "cannot index into a value of type `{}`",
+                                                   base_t);
+                            // Try to give some advice about indexing tuples.
+                            if let ty::TyTuple(..) = base_t.sty {
+                                let mut needs_note = true;
+                                // If the index is an integer, we can show the actual
+                                // fixed expression:
+                                if let hir::ExprLit(ref lit) = idx.node {
+                                    if let ast::LitKind::Int(i,
                                             ast::LitIntType::Unsuffixed) = lit.node {
-                                      let snip = tcx.sess.codemap().span_to_snippet(base.span);
-                                      if let Ok(snip) = snip {
-                                          err.span_suggestion(expr.span,
-                                                              "to access tuple elements, use",
-                                                              format!("{}.{}", snip, i));
-                                          needs_note = false;
-                                      }
-                                  }
-                              }
-                              if needs_note {
-                                  err.help("to access tuple elements, use tuple indexing \
+                                        let snip = tcx.sess.codemap().span_to_snippet(base.span);
+                                        if let Ok(snip) = snip {
+                                            err.span_suggestion(expr.span,
+                                                                "to access tuple elements, use",
+                                                                format!("{}.{}", snip, i));
+                                            needs_note = false;
+                                        }
+                                    }
+                                }
+                                if needs_note {
+                                    err.help("to access tuple elements, use tuple indexing \
                                             syntax (e.g. `tuple.0`)");
-                              }
-                          }
-                          err.emit();
-                          self.tcx.types.err
-                      }
-                  }
-              }
-           }
-          hir::ExprYield(ref value) => {
-            match self.yield_ty {
-                Some(ty) => {
-                    self.check_expr_coercable_to_type(&value, ty);
+                                }
+                            }
+                            err.emit();
+                            self.tcx.types.err
+                        }
+                    }
                 }
-                None => {
-                    struct_span_err!(self.tcx.sess, expr.span, E0627,
-                                 "yield statement outside of generator literal").emit();
+            }
+            hir::ExprYield(ref value) => {
+                match self.yield_ty {
+                    Some(ty) => {
+                        self.check_expr_coercable_to_type(&value, ty);
+                    }
+                    None => {
+                        struct_span_err!(self.tcx.sess, expr.span, E0627,
+                                        "yield statement outside of generator literal").emit();
+                    }
                 }
+                tcx.mk_nil()
             }
-            tcx.mk_nil()
-          }
         }
     }
 
@@ -4740,8 +4749,7 @@ pub fn instantiate_value_path(&self,
             Def::Fn(def_id) |
             Def::Const(def_id) |
             Def::Static(def_id, _) => {
-                fn_segment = Some((segments.last().unwrap(),
-                                   self.tcx.generics_of(def_id)));
+                fn_segment = Some((segments.last().unwrap(), self.tcx.generics_of(def_id)));
             }
 
             // Case 3. Reference to a method or associated const.
@@ -4781,7 +4789,7 @@ pub fn instantiate_value_path(&self,
         // errors if type parameters are provided in an inappropriate place.
         let poly_segments = type_segment.is_some() as usize +
                             fn_segment.is_some() as usize;
-        AstConv::prohibit_type_params(self, &segments[..segments.len() - poly_segments]);
+        AstConv::prohibit_generics(self, &segments[..segments.len() - poly_segments]);
 
         match def {
             Def::Local(nid) | Def::Upvar(nid, ..) => {
@@ -4800,8 +4808,8 @@ pub fn instantiate_value_path(&self,
         // to add defaults. If the user provided *too many* types, that's
         // a problem.
         let supress_mismatch = self.check_impl_trait(span, fn_segment);
-        self.check_path_parameter_count(span, &mut type_segment, false, supress_mismatch);
-        self.check_path_parameter_count(span, &mut fn_segment, false, supress_mismatch);
+        self.check_generic_arg_count(span, &mut type_segment, false, supress_mismatch);
+        self.check_generic_arg_count(span, &mut fn_segment, false, supress_mismatch);
 
         let (fn_start, has_self) = match (type_segment, fn_segment) {
             (_, Some((_, generics))) => {
@@ -4812,11 +4820,42 @@ pub fn instantiate_value_path(&self,
             }
             (None, None) => (0, false)
         };
+        // FIXME(varkor): Separating out the parameters is messy.
+        let mut lifetimes_type_seg = vec![];
+        let mut types_type_seg = vec![];
+        let mut infer_types_type_seg = true;
+        if let Some((seg, _)) = type_segment {
+            if let Some(ref data) = seg.args {
+                for arg in &data.args {
+                    match arg {
+                        GenericArg::Lifetime(lt) => lifetimes_type_seg.push(lt),
+                        GenericArg::Type(ty) => types_type_seg.push(ty),
+                    }
+                }
+            }
+            infer_types_type_seg = seg.infer_types;
+        }
+
+        let mut lifetimes_fn_seg = vec![];
+        let mut types_fn_seg = vec![];
+        let mut infer_types_fn_seg = true;
+        if let Some((seg, _)) = fn_segment {
+            if let Some(ref data) = seg.args {
+                for arg in &data.args {
+                    match arg {
+                        GenericArg::Lifetime(lt) => lifetimes_fn_seg.push(lt),
+                        GenericArg::Type(ty) => types_fn_seg.push(ty),
+                    }
+                }
+            }
+            infer_types_fn_seg = seg.infer_types;
+        }
+
         let substs = Substs::for_item(self.tcx, def.def_id(), |param, substs| {
             let mut i = param.index as usize;
 
-            let segment = if i < fn_start {
-                if let GenericParamDefKind::Type {..} = param.kind {
+            let (segment, lifetimes, types, infer_types) = if i < fn_start {
+                if let GenericParamDefKind::Type { .. } = param.kind {
                     // Handle Self first, so we can adjust the index to match the AST.
                     if has_self && i == 0 {
                         return opt_self_ty.map(|ty| ty.into()).unwrap_or_else(|| {
@@ -4825,29 +4864,21 @@ pub fn instantiate_value_path(&self,
                     }
                 }
                 i -= has_self as usize;
-                type_segment
+                (type_segment, &lifetimes_type_seg, &types_type_seg, infer_types_type_seg)
             } else {
                 i -= fn_start;
-                fn_segment
+                (fn_segment, &lifetimes_fn_seg, &types_fn_seg, infer_types_fn_seg)
             };
 
             match param.kind {
                 GenericParamDefKind::Lifetime => {
-                    let lifetimes = segment.map_or(&[][..], |(s, _)| {
-                        s.parameters.as_ref().map_or(&[][..], |p| &p.lifetimes[..])
-                    });
-
                     if let Some(lifetime) = lifetimes.get(i) {
                         AstConv::ast_region_to_region(self, lifetime, Some(param)).into()
                     } else {
                         self.re_infer(span, Some(param)).unwrap().into()
                     }
                 }
-                GenericParamDefKind::Type {..} => {
-                    let (types, infer_types) = segment.map_or((&[][..], true), |(s, _)| {
-                        (s.parameters.as_ref().map_or(&[][..], |p| &p.types[..]), s.infer_types)
-                    });
-
+                GenericParamDefKind::Type { .. } => {
                     // Skip over the lifetimes in the same segment.
                     if let Some((_, generics)) = segment {
                         i -= generics.own_counts().lifetimes;
@@ -4955,25 +4986,26 @@ fn check_rustc_args_require_const(&self,
     }
 
     /// Report errors if the provided parameters are too few or too many.
-    fn check_path_parameter_count(&self,
-                                  span: Span,
-                                  segment: &mut Option<(&hir::PathSegment, &ty::Generics)>,
-                                  is_method_call: bool,
-                                  supress_mismatch_error: bool) {
+    fn check_generic_arg_count(&self,
+                               span: Span,
+                               segment: &mut Option<(&hir::PathSegment, &ty::Generics)>,
+                               is_method_call: bool,
+                               supress_mismatch_error: bool) {
         let (lifetimes, types, infer_types, bindings) = segment.map_or(
-            (&[][..], &[][..], true, &[][..]),
-            |(s, _)| s.parameters.as_ref().map_or(
-                (&[][..], &[][..], s.infer_types, &[][..]),
-                |p| (&p.lifetimes[..], &p.types[..],
-                     s.infer_types, &p.bindings[..])));
-        let infer_lifetimes = lifetimes.len() == 0;
-
-        let count_lifetime_params = |n| {
-            format!("{} lifetime parameter{}", n, if n == 1 { "" } else { "s" })
-        };
-        let count_type_params = |n| {
-            format!("{} type parameter{}", n, if n == 1 { "" } else { "s" })
-        };
+            (vec![], vec![], true, &[][..]),
+            |(s, _)| {
+                s.args.as_ref().map_or(
+                    (vec![], vec![], s.infer_types, &[][..]),
+                    |data| {
+                        let (mut lifetimes, mut types) = (vec![], vec![]);
+                        data.args.iter().for_each(|arg| match arg {
+                            GenericArg::Lifetime(lt) => lifetimes.push(lt),
+                            GenericArg::Type(ty) => types.push(ty),
+                        });
+                        (lifetimes, types, s.infer_types, &data.bindings[..])
+                    }
+                )
+            });
 
         // Check provided parameters.
         let ((ty_required, ty_accepted), lt_accepted) =
@@ -4987,9 +5019,7 @@ struct ParamRange {
                 let mut ty_params = ParamRange { required: 0, accepted: 0 };
                 for param in &generics.params {
                     match param.kind {
-                        GenericParamDefKind::Lifetime => {
-                            lt_accepted += 1;
-                        }
+                        GenericParamDefKind::Lifetime => lt_accepted += 1,
                         GenericParamDefKind::Type { has_default, .. } => {
                             ty_params.accepted += 1;
                             if !has_default {
@@ -5006,36 +5036,37 @@ struct ParamRange {
                 ((ty_params.required, ty_params.accepted), lt_accepted)
             });
 
-        if types.len() > ty_accepted {
-            let span = types[ty_accepted].span;
-            let expected_text = count_type_params(ty_accepted);
-            let actual_text = count_type_params(types.len());
-            struct_span_err!(self.tcx.sess, span, E0087,
-                             "too many type parameters provided: \
-                              expected at most {}, found {}",
-                             expected_text, actual_text)
-                .span_label(span, format!("expected {}", expected_text))
-                .emit();
-
+        let count_type_params = |n| {
+            format!("{} type parameter{}", n, if n == 1 { "" } else { "s" })
+        };
+        let expected_text = count_type_params(ty_accepted);
+        let actual_text = count_type_params(types.len());
+        if let Some((mut err, span)) = if types.len() > ty_accepted {
             // To prevent derived errors to accumulate due to extra
             // type parameters, we force instantiate_value_path to
             // use inference variables instead of the provided types.
             *segment = None;
+            let span = types[ty_accepted].span;
+            Some((struct_span_err!(self.tcx.sess, span, E0087,
+                                  "too many type parameters provided: \
+                                  expected at most {}, found {}",
+                                  expected_text, actual_text), span))
         } else if types.len() < ty_required && !infer_types && !supress_mismatch_error {
-            let expected_text = count_type_params(ty_required);
-            let actual_text = count_type_params(types.len());
-            struct_span_err!(self.tcx.sess, span, E0089,
-                             "too few type parameters provided: \
-                              expected {}, found {}",
-                             expected_text, actual_text)
-                .span_label(span, format!("expected {}", expected_text))
-                .emit();
+            Some((struct_span_err!(self.tcx.sess, span, E0089,
+                                  "too few type parameters provided: \
+                                  expected {}, found {}",
+                                  expected_text, actual_text), span))
+        } else {
+            None
+        } {
+            err.span_label(span, format!("expected {}", expected_text)).emit();
         }
 
         if !bindings.is_empty() {
             AstConv::prohibit_projection(self, bindings[0].span);
         }
 
+        let infer_lifetimes = lifetimes.len() == 0;
         // Prohibit explicit lifetime arguments if late bound lifetime parameters are present.
         let has_late_bound_lifetime_defs =
             segment.map_or(None, |(_, generics)| generics.has_late_bound_regions);
@@ -5059,25 +5090,26 @@ struct ParamRange {
             return;
         }
 
-        if lifetimes.len() > lt_accepted {
+        let count_lifetime_params = |n| {
+            format!("{} lifetime parameter{}", n, if n == 1 { "" } else { "s" })
+        };
+        let expected_text = count_lifetime_params(lt_accepted);
+        let actual_text = count_lifetime_params(lifetimes.len());
+        if let Some((mut err, span)) = if lifetimes.len() > lt_accepted {
             let span = lifetimes[lt_accepted].span;
-            let expected_text = count_lifetime_params(lt_accepted);
-            let actual_text = count_lifetime_params(lifetimes.len());
-            struct_span_err!(self.tcx.sess, span, E0088,
-                             "too many lifetime parameters provided: \
-                              expected at most {}, found {}",
-                             expected_text, actual_text)
-                .span_label(span, format!("expected {}", expected_text))
-                .emit();
+            Some((struct_span_err!(self.tcx.sess, span, E0088,
+                                  "too many lifetime parameters provided: \
+                                  expected at most {}, found {}",
+                                  expected_text, actual_text), span))
         } else if lifetimes.len() < lt_accepted && !infer_lifetimes {
-            let expected_text = count_lifetime_params(lt_accepted);
-            let actual_text = count_lifetime_params(lifetimes.len());
-            struct_span_err!(self.tcx.sess, span, E0090,
-                             "too few lifetime parameters provided: \
-                              expected {}, found {}",
-                             expected_text, actual_text)
-                .span_label(span, format!("expected {}", expected_text))
-                .emit();
+            Some((struct_span_err!(self.tcx.sess, span, E0090,
+                                  "too few lifetime parameters provided: \
+                                  expected {}, found {}",
+                                  expected_text, actual_text), span))
+        } else {
+            None
+        } {
+            err.span_label(span, format!("expected {}", expected_text)).emit();
         }
     }
 
@@ -5088,13 +5120,11 @@ fn check_impl_trait(&self,
                         -> bool {
         let segment = segment.map(|(path_segment, generics)| {
             let explicit = !path_segment.infer_types;
-            let impl_trait = generics.params.iter().any(|param| {
-                match param.kind {
-                    ty::GenericParamDefKind::Type {
-                        synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), ..
-                    } => true,
-                    _ => false,
-                }
+            let impl_trait = generics.params.iter().any(|param| match param.kind {
+                ty::GenericParamDefKind::Type {
+                    synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), ..
+                } => true,
+                _ => false,
             });
 
             if explicit && impl_trait {
@@ -5155,34 +5185,39 @@ fn with_breakable_ctxt<F: FnOnce() -> R, R>(&self, id: ast::NodeId,
 }
 
 pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                       generics: &hir::Generics,
+                                       generics: &ty::Generics,
                                        ty: Ty<'tcx>) {
-    debug!("check_bounds_are_used(n_tps={}, ty={:?})",
-           generics.ty_params().count(),  ty);
-
-    // make a vector of booleans initially false, set to true when used
-    if generics.ty_params().next().is_none() { return; }
-    let mut tps_used = vec![false; generics.ty_params().count()];
+    let own_counts = generics.own_counts();
+    debug!("check_bounds_are_used(n_tps={}, ty={:?})", own_counts.types, ty);
 
-    let lifetime_count = generics.lifetimes().count();
+    if own_counts.types == 0 {
+        return;
+    }
+    // Make a vector of booleans initially false, set to true when used.
+    let mut types_used = vec![false; own_counts.types];
 
     for leaf_ty in ty.walk() {
-        if let ty::TyParam(ty::ParamTy {idx, ..}) = leaf_ty.sty {
+        if let ty::TyParam(ty::ParamTy { idx, .. }) = leaf_ty.sty {
             debug!("Found use of ty param num {}", idx);
-            tps_used[idx as usize - lifetime_count] = true;
+            types_used[idx as usize - own_counts.lifetimes] = true;
         } else if let ty::TyError = leaf_ty.sty {
-            // If there already another error, do not emit an error for not using a type Parameter
+            // If there is already another error, do not emit
+            // an error for not using a type Parameter.
             assert!(tcx.sess.err_count() > 0);
             return;
         }
     }
 
-    for (&used, param) in tps_used.iter().zip(generics.ty_params()) {
+    let types = generics.params.iter().filter(|param| match param.kind {
+        ty::GenericParamDefKind::Type { .. } => true,
+        _ => false,
+    });
+    for (&used, param) in types_used.iter().zip(types) {
         if !used {
-            struct_span_err!(tcx.sess, param.span, E0091,
-                "type parameter `{}` is unused",
-                param.name)
-                .span_label(param.span, "unused type parameter")
+            let id = tcx.hir.as_local_node_id(param.def_id).unwrap();
+            let span = tcx.hir.span(id);
+            struct_span_err!(tcx.sess, span, E0091, "type parameter `{}` is unused", param.name)
+                .span_label(span, "unused type parameter")
                 .emit();
         }
     }
index cfb9c2a50620e3c5e1e8b514dcaa9e1ae2c84e55..e24269bca571d67352198a86ab69fbf21c1a5322 100644 (file)
@@ -111,6 +111,10 @@ fn analyze_closure(
         let (closure_def_id, substs) = match self.node_ty(closure_hir_id).sty {
             ty::TyClosure(def_id, substs) => (def_id, UpvarSubsts::Closure(substs)),
             ty::TyGenerator(def_id, substs, _) => (def_id, UpvarSubsts::Generator(substs)),
+            ty::TyError => {
+                // #51714: skip analysis when we have already encountered type errors
+                return;
+            }
             ref t => {
                 span_bug!(
                     span,
index 7a2c38468e0448735811240adf0cbe4dc2ee2fe1..b61f09cbaea6d22b2789f476416768f0f039dd7a 100644 (file)
@@ -602,8 +602,8 @@ fn check_method_receiver<'fcx, 'gcx, 'tcx>(fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
 }
 
 fn check_variances_for_type_defn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                    item: &hir::Item,
-                                    ast_generics: &hir::Generics)
+                                           item: &hir::Item,
+                                           hir_generics: &hir::Generics)
 {
     let item_def_id = tcx.hir.local_def_id(item.id);
     let ty = tcx.type_of(item_def_id);
@@ -631,11 +631,8 @@ fn check_variances_for_type_defn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             continue;
         }
 
-        let (span, name) = match ast_generics.params[index] {
-            hir::GenericParam::Lifetime(ref ld) => (ld.lifetime.span, ld.lifetime.name.name()),
-            hir::GenericParam::Type(ref tp) => (tp.span, tp.name),
-        };
-        report_bivariance(tcx, span, name);
+        let param = &hir_generics.params[index];
+        report_bivariance(tcx, param.span, param.name.name());
     }
 }
 
@@ -663,17 +660,12 @@ fn report_bivariance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 fn reject_shadowing_parameters(tcx: TyCtxt, def_id: DefId) {
     let generics = tcx.generics_of(def_id);
     let parent = tcx.generics_of(generics.parent.unwrap());
-    let impl_params: FxHashMap<_, _> =
-        parent.params.iter()
-                     .flat_map(|param| {
-                         match param.kind {
-                             GenericParamDefKind::Lifetime => None,
-                             GenericParamDefKind::Type {..} => Some((param.name, param.def_id)),
-                         }
-                     })
-                     .collect();
-
-    for method_param in generics.params.iter() {
+    let impl_params: FxHashMap<_, _> = parent.params.iter().flat_map(|param| match param.kind {
+        GenericParamDefKind::Lifetime => None,
+        GenericParamDefKind::Type {..} => Some((param.name, param.def_id)),
+    }).collect();
+
+    for method_param in &generics.params {
         match method_param.kind {
             // Shadowing is checked in resolve_lifetime.
             GenericParamDefKind::Lifetime => continue,
index 4aa876e85b69a5e2d0e1ee60e2c1f2cc43185fbb..5a442881a631582a539d625c0141ada151845590 100644 (file)
@@ -35,7 +35,9 @@ fn check_unsafety_coherence(&mut self,
 
             Some(trait_ref) => {
                 let trait_def = self.tcx.trait_def(trait_ref.def_id);
-                let unsafe_attr = impl_generics.and_then(|g| g.carries_unsafe_attr());
+                let unsafe_attr = impl_generics.and_then(|generics| {
+                    generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle")
+                });
                 match (trait_def.unsafety, unsafe_attr, unsafety, polarity) {
                     (Unsafety::Normal, None, Unsafety::Unsafe, hir::ImplPolarity::Positive) => {
                         span_err!(self.tcx.sess,
@@ -53,13 +55,14 @@ fn check_unsafety_coherence(&mut self,
                                   trait_ref);
                     }
 
-                    (Unsafety::Normal, Some(g), Unsafety::Normal, hir::ImplPolarity::Positive) =>
+                    (Unsafety::Normal, Some(attr_name), Unsafety::Normal,
+                        hir::ImplPolarity::Positive) =>
                     {
                         span_err!(self.tcx.sess,
                                   item.span,
                                   E0569,
                                   "requires an `unsafe impl` declaration due to `#[{}]` attribute",
-                                  g.attr_name());
+                                  attr_name);
                     }
 
                     (_, _, Unsafety::Unsafe, hir::ImplPolarity::Negative) => {
index 58e804fc13f2d8c9497f04672c4b528fa0fada04..c24e20c5699092189f939316583910f7006afb54 100644 (file)
@@ -49,6 +49,7 @@
 use syntax_pos::{Span, DUMMY_SP};
 
 use rustc::hir::{self, map as hir_map, CodegenFnAttrs, CodegenFnAttrFlags, Unsafety};
+use rustc::hir::GenericParamKind;
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::hir::def::{Def, CtorKind};
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
@@ -113,10 +114,14 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
     }
 
     fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
-        for param in generics.ty_params() {
-            if param.default.is_some() {
-                let def_id = self.tcx.hir.local_def_id(param.id);
-                self.tcx.type_of(def_id);
+        for param in &generics.params {
+            match param.kind {
+                hir::GenericParamKind::Lifetime { .. } => {}
+                hir::GenericParamKind::Type { default: Some(_), .. } => {
+                    let def_id = self.tcx.hir.local_def_id(param.id);
+                    self.tcx.type_of(def_id);
+                }
+                hir::GenericParamKind::Type { .. } => {}
             }
         }
         intravisit::walk_generics(self, generics);
@@ -308,9 +313,12 @@ fn type_parameter_bounds_in_generics(&self,
                                          -> Vec<ty::Predicate<'tcx>>
     {
         let from_ty_params =
-            ast_generics.ty_params()
-                .filter(|p| p.id == param_id)
-                .flat_map(|p| p.bounds.iter())
+            ast_generics.params.iter()
+                .filter_map(|param| match param.kind {
+                    GenericParamKind::Type { .. } if param.id == param_id => Some(&param.bounds),
+                    _ => None
+                })
+                .flat_map(|bounds| bounds.iter())
                 .flat_map(|b| predicates_from_bound(self, ty, b));
 
         let from_where_clauses =
@@ -739,10 +747,15 @@ fn has_late_bound_regions<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             outer_index: ty::INNERMOST,
             has_late_bound_regions: None,
         };
-        for lifetime in generics.lifetimes() {
-            let hir_id = tcx.hir.node_to_hir_id(lifetime.lifetime.id);
-            if tcx.is_late_bound(hir_id) {
-                return Some(lifetime.lifetime.span);
+        for param in &generics.params {
+            match param.kind {
+                GenericParamKind::Lifetime { .. } => {
+                    let hir_id = tcx.hir.node_to_hir_id(param.id);
+                    if tcx.is_late_bound(hir_id) {
+                        return Some(param.span);
+                    }
+                }
+                _ => {},
             }
         }
         visitor.visit_fn_decl(decl);
@@ -883,12 +896,12 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let mut params: Vec<_> = opt_self.into_iter().collect();
 
     let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics);
-    params.extend(early_lifetimes.enumerate().map(|(i, l)| {
+    params.extend(early_lifetimes.enumerate().map(|(i, param)| {
         ty::GenericParamDef {
-            name: l.lifetime.name.name().as_interned_str(),
+            name: param.name.name().as_interned_str(),
             index: own_start + i as u32,
-            def_id: tcx.hir.local_def_id(l.lifetime.id),
-            pure_wrt_drop: l.pure_wrt_drop,
+            def_id: tcx.hir.local_def_id(param.id),
+            pure_wrt_drop: param.pure_wrt_drop,
             kind: ty::GenericParamDefKind::Lifetime,
         }
     }));
@@ -898,34 +911,40 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     // Now create the real type parameters.
     let type_start = own_start - has_self as u32 + params.len() as u32;
-    params.extend(ast_generics.ty_params().enumerate().map(|(i, p)| {
-        if p.name == keywords::SelfType.name() {
-            span_bug!(p.span, "`Self` should not be the name of a regular parameter");
-        }
-
-        if !allow_defaults && p.default.is_some() {
-            if !tcx.features().default_type_parameter_fallback {
-                tcx.lint_node(
-                    lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
-                    p.id,
-                    p.span,
-                    &format!("defaults for type parameters are only allowed in `struct`, \
-                              `enum`, `type`, or `trait` definitions."));
+    let mut i = 0;
+    params.extend(ast_generics.params.iter().filter_map(|param| match param.kind {
+        GenericParamKind::Type { ref default, synthetic, .. } => {
+            if param.name.name() == keywords::SelfType.name() {
+                span_bug!(param.span,  "`Self` should not be the name of a regular parameter");
             }
-        }
 
-        ty::GenericParamDef {
-            index: type_start + i as u32,
-            name: p.name.as_interned_str(),
-            def_id: tcx.hir.local_def_id(p.id),
-            pure_wrt_drop: p.pure_wrt_drop,
-            kind: ty::GenericParamDefKind::Type {
-                has_default: p.default.is_some(),
-                object_lifetime_default:
-                    object_lifetime_defaults.as_ref().map_or(rl::Set1::Empty, |o| o[i]),
-                synthetic: p.synthetic,
-            },
+            if !allow_defaults && default.is_some() {
+                if !tcx.features().default_type_parameter_fallback {
+                    tcx.lint_node(
+                        lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
+                        param.id,
+                        param.span,
+                        &format!("defaults for type parameters are only allowed in \
+                                    `struct`, `enum`, `type`, or `trait` definitions."));
+                }
+            }
+
+            let ty_param = ty::GenericParamDef {
+                index: type_start + i as u32,
+                name: param.name.name().as_interned_str(),
+                def_id: tcx.hir.local_def_id(param.id),
+                pure_wrt_drop: param.pure_wrt_drop,
+                kind: ty::GenericParamDefKind::Type {
+                    has_default: default.is_some(),
+                    object_lifetime_default:
+                        object_lifetime_defaults.as_ref().map_or(rl::Set1::Empty, |o| o[i]),
+                    synthetic,
+                },
+            };
+            i += 1;
+            Some(ty_param)
         }
+        _ => None,
     }));
 
     // provide junk type parameter defs - the only place that
@@ -1047,7 +1066,24 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 ItemExistential(hir::ExistTy { impl_trait_fn: None, .. }) => unimplemented!(),
                 // existential types desugared from impl Trait
                 ItemExistential(hir::ExistTy { impl_trait_fn: Some(owner), .. }) => {
-                    tcx.typeck_tables_of(owner).concrete_existential_types[&def_id]
+                    tcx.typeck_tables_of(owner).concrete_existential_types
+                        .get(&def_id)
+                        .cloned()
+                        .unwrap_or_else(|| {
+                            // This can occur if some error in the
+                            // owner fn prevented us from populating
+                            // the `concrete_existential_types` table.
+                            tcx.sess.delay_span_bug(
+                                DUMMY_SP,
+                                &format!(
+                                    "owner {:?} has no existential type for {:?} in its tables",
+                                    owner,
+                                    def_id,
+                                ),
+                            );
+
+                            tcx.types.err
+                        })
                 },
                 ItemTrait(..) | ItemTraitAlias(..) |
                 ItemMod(..) |
@@ -1119,8 +1155,13 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             }
         },
 
-        NodeTyParam(&hir::TyParam { default: Some(ref ty), .. }) => {
-            icx.to_ty(ty)
+        NodeGenericParam(param) => {
+            match param.kind {
+                hir::GenericParamKind::Type { default: Some(ref ty), .. } => {
+                    icx.to_ty(ty)
+                }
+                _ => bug!("unexpected non-type NodeGenericParam"),
+            }
         }
 
         x => {
@@ -1140,13 +1181,13 @@ fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let icx = ItemCtxt::new(tcx, def_id);
 
     match tcx.hir.get(node_id) {
-        NodeTraitItem(&hir::TraitItem { node: TraitItemKind::Method(ref sig, _), .. }) |
-        NodeImplItem(&hir::ImplItem { node: ImplItemKind::Method(ref sig, _), .. }) => {
-            AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl)
+        NodeTraitItem(hir::TraitItem { node: TraitItemKind::Method(sig, _), .. }) |
+        NodeImplItem(hir::ImplItem { node: ImplItemKind::Method(sig, _), .. }) => {
+            AstConv::ty_of_fn(&icx, sig.header.unsafety, sig.header.abi, &sig.decl)
         }
 
-        NodeItem(&hir::Item { node: ItemFn(ref decl, unsafety, _, abi, _, _), .. }) => {
-            AstConv::ty_of_fn(&icx, unsafety, abi, decl)
+        NodeItem(hir::Item { node: ItemFn(decl, header, _, _), .. }) => {
+            AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl)
         }
 
         NodeForeignItem(&hir::ForeignItem { node: ForeignItemFn(ref fn_decl, _, _), .. }) => {
@@ -1225,7 +1266,7 @@ fn impl_polarity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
 // Is it marked with ?Sized
 fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
-                                ast_bounds: &[hir::TyParamBound],
+                                ast_bounds: &[hir::GenericBound],
                                 span: Span) -> bool
 {
     let tcx = astconv.tcx();
@@ -1233,7 +1274,7 @@ fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
     // Try to find an unbound in bounds.
     let mut unbound = None;
     for ab in ast_bounds {
-        if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab  {
+        if let &hir::GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = ab  {
             if unbound.is_none() {
                 unbound = Some(ptr.trait_ref.clone());
             } else {
@@ -1274,15 +1315,16 @@ fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
 /// `resolve_lifetime::early_bound_lifetimes`.
 fn early_bound_lifetimes_from_generics<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    ast_generics: &'a hir::Generics)
-    -> impl Iterator<Item=&'a hir::LifetimeDef> + Captures<'tcx>
+    generics: &'a hir::Generics)
+    -> impl Iterator<Item=&'a hir::GenericParam> + Captures<'tcx>
 {
-    ast_generics
-        .lifetimes()
-        .filter(move |l| {
-            let hir_id = tcx.hir.node_to_hir_id(l.lifetime.id);
+    generics.params.iter().filter(move |param| match param.kind {
+        GenericParamKind::Lifetime { .. } => {
+            let hir_id = tcx.hir.node_to_hir_id(param.id);
             !tcx.is_late_bound(hir_id)
-        })
+        }
+        _ => false,
+    })
 }
 
 fn predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -1410,31 +1452,42 @@ pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let mut index = parent_count + has_own_self as u32;
     for param in early_bound_lifetimes_from_generics(tcx, ast_generics) {
         let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
-            def_id: tcx.hir.local_def_id(param.lifetime.id),
+            def_id: tcx.hir.local_def_id(param.id),
             index,
-            name: param.lifetime.name.name().as_interned_str(),
+            name: param.name.name().as_interned_str(),
         }));
         index += 1;
 
-        for bound in &param.bounds {
-            let bound_region = AstConv::ast_region_to_region(&icx, bound, None);
-            let outlives = ty::Binder::bind(ty::OutlivesPredicate(region, bound_region));
-            predicates.push(outlives.to_predicate());
+        match param.kind {
+            GenericParamKind::Lifetime { .. } => {
+                param.bounds.iter().for_each(|bound| match bound {
+                    hir::GenericBound::Outlives(lt) => {
+                        let bound = AstConv::ast_region_to_region(&icx, &lt, None);
+                        let outlives = ty::Binder::bind(ty::OutlivesPredicate(region, bound));
+                        predicates.push(outlives.to_predicate());
+                    }
+                    _ => bug!(),
+                });
+            },
+            _ => bug!(),
         }
     }
 
     // Collect the predicates that were written inline by the user on each
     // type parameter (e.g., `<T:Foo>`).
-    for param in ast_generics.ty_params() {
-        let param_ty = ty::ParamTy::new(index, param.name.as_interned_str()).to_ty(tcx);
-        index += 1;
-
-        let bounds = compute_bounds(&icx,
-                                    param_ty,
-                                    &param.bounds,
-                                    SizedByDefault::Yes,
-                                    param.span);
-        predicates.extend(bounds.predicates(tcx, param_ty));
+    for param in &ast_generics.params {
+        match param.kind {
+            GenericParamKind::Type { .. } => {
+                let name = param.name.name().as_interned_str();
+                let param_ty = ty::ParamTy::new(index, name).to_ty(tcx);
+                index += 1;
+
+                let sized = SizedByDefault::Yes;
+                let bounds = compute_bounds(&icx, param_ty, &param.bounds, sized, param.span);
+                predicates.extend(bounds.predicates(tcx, param_ty));
+            }
+            _ => {}
+        }
     }
 
     // Add in the bounds that appear in the where-clause
@@ -1446,7 +1499,7 @@ pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
                 for bound in bound_pred.bounds.iter() {
                     match bound {
-                        &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
+                        &hir::GenericBound::Trait(ref poly_trait_ref, _) => {
                             let mut projections = Vec::new();
 
                             let trait_ref =
@@ -1462,7 +1515,7 @@ pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             }
                         }
 
-                        &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
+                        &hir::GenericBound::Outlives(ref lifetime) => {
                             let region = AstConv::ast_region_to_region(&icx,
                                                                        lifetime,
                                                                        None);
@@ -1476,7 +1529,12 @@ pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             &hir::WherePredicate::RegionPredicate(ref region_pred) => {
                 let r1 = AstConv::ast_region_to_region(&icx, &region_pred.lifetime, None);
                 for bound in &region_pred.bounds {
-                    let r2 = AstConv::ast_region_to_region(&icx, bound, None);
+                    let r2 = match bound {
+                        hir::GenericBound::Outlives(lt) => {
+                            AstConv::ast_region_to_region(&icx, lt, None)
+                        }
+                        _ => bug!(),
+                    };
                     let pred = ty::Binder::bind(ty::OutlivesPredicate(r1, r2));
                     predicates.push(ty::Predicate::RegionOutlives(pred))
                 }
@@ -1541,7 +1599,7 @@ pub enum SizedByDefault { Yes, No, }
 /// built-in trait (formerly known as kind): Send.
 pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
                                         param_ty: Ty<'tcx>,
-                                        ast_bounds: &[hir::TyParamBound],
+                                        ast_bounds: &[hir::GenericBound],
                                         sized_by_default: SizedByDefault,
                                         span: Span)
                                         -> Bounds<'tcx>
@@ -1550,22 +1608,16 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
     let mut trait_bounds = vec![];
     for ast_bound in ast_bounds {
         match *ast_bound {
-            hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => {
-                trait_bounds.push(b);
-            }
-            hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {}
-            hir::RegionTyParamBound(ref l) => {
-                region_bounds.push(l);
-            }
+            hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::None) => trait_bounds.push(b),
+            hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => {}
+            hir::GenericBound::Outlives(ref l) => region_bounds.push(l),
         }
     }
 
     let mut projection_bounds = vec![];
 
     let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| {
-        astconv.instantiate_poly_trait_ref(bound,
-                                           param_ty,
-                                           &mut projection_bounds)
+        astconv.instantiate_poly_trait_ref(bound, param_ty, &mut projection_bounds)
     }).collect();
 
     let region_bounds = region_bounds.into_iter().map(|r| {
@@ -1588,18 +1640,18 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
     }
 }
 
-/// Converts a specific TyParamBound from the AST into a set of
+/// Converts a specific GenericBound from the AST into a set of
 /// predicates that apply to the self-type. A vector is returned
 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
 /// and `<T as Bar>::X == i32`).
 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
                                param_ty: Ty<'tcx>,
-                               bound: &hir::TyParamBound)
+                               bound: &hir::GenericBound)
                                -> Vec<ty::Predicate<'tcx>>
 {
     match *bound {
-        hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
+        hir::GenericBound::Trait(ref tr, hir::TraitBoundModifier::None) => {
             let mut projections = Vec::new();
             let pred = astconv.instantiate_poly_trait_ref(tr,
                                                           param_ty,
@@ -1609,14 +1661,12 @@ fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
                        .chain(Some(pred.to_predicate()))
                        .collect()
         }
-        hir::RegionTyParamBound(ref lifetime) => {
+        hir::GenericBound::Outlives(ref lifetime) => {
             let region = astconv.ast_region_to_region(lifetime, None);
             let pred = ty::Binder::bind(ty::OutlivesPredicate(param_ty, region));
             vec![ty::Predicate::TypeOutlives(pred)]
         }
-        hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
-            Vec::new()
-        }
+        hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => vec![],
     }
 }
 
@@ -1848,11 +1898,18 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
                 }
             });
         } else if attr.check_name("export_name") {
-            if let s @ Some(_) = attr.value_str() {
-                codegen_fn_attrs.export_name = s;
+            if let Some(s) = attr.value_str() {
+                if s.as_str().contains("\0") {
+                    // `#[export_name = ...]` will be converted to a null-terminated string,
+                    // so it may not contain any null characters.
+                    struct_span_err!(tcx.sess, attr.span, E0648,
+                                     "`export_name` may not contain null characters")
+                        .emit();
+                }
+                codegen_fn_attrs.export_name = Some(s);
             } else {
                 struct_span_err!(tcx.sess, attr.span, E0558,
-                                    "export_name attribute has invalid format")
+                                 "`export_name` attribute has invalid format")
                     .span_label(attr.span, "did you mean #[export_name=\"*\"]?")
                     .emit();
             }
index da54eeabdb97be3727f73dc4df57c24731b5c5b8..b0b72256edccf69f75bb139a9c789937b7f97e99 100644 (file)
@@ -1501,12 +1501,12 @@ struct Foo {
 "##,
 
 E0131: r##"
-It is not possible to define `main` with type parameters, or even with function
-parameters. When `main` is present, it must take no arguments and return `()`.
+It is not possible to define `main` with generic parameters.
+When `main` is present, it must take no arguments and return `()`.
 Erroneous code example:
 
 ```compile_fail,E0131
-fn main<T>() { // error: main function is not allowed to have type parameters
+fn main<T>() { // error: main function is not allowed to have generic parameters
 }
 ```
 "##,
@@ -3709,7 +3709,7 @@ fn main() {}
 Erroneous code example:
 
 ```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
-#[export_name] // error: export_name attribute has invalid format
+#[export_name] // error: `export_name` attribute has invalid format
 pub fn something() {}
 
 fn main() {}
@@ -4545,6 +4545,15 @@ fn start(_: isize, _: *const *const u8) -> isize where (): Copy {
 ```
 "##,
 
+E0648: r##"
+`export_name` attributes may not contain null characters (`\0`).
+
+```compile_fail,E0648
+#[export_name="\0foo"] // error: `export_name` may not contain null characters
+pub fn bar() {}
+```
+"##,
+
 E0689: r##"
 This error indicates that the numeric value for the method being passed exists
 but the type of the numeric value or binding could not be identified.
index 80f57adf580bfc6b5743025a4a812c2c14effd55..dcc5fa53d2f420f9c0e75c6cc0464d00b1f37781 100644 (file)
@@ -76,6 +76,7 @@
 #![feature(crate_visibility_modifier)]
 #![feature(from_ref)]
 #![feature(exhaustive_patterns)]
+#![feature(iterator_find_map)]
 #![feature(quote)]
 #![feature(refcell_replace_swap)]
 #![feature(rustc_diagnostic_macros)]
@@ -190,16 +191,9 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                         hir::ItemFn(.., ref generics, _) => {
                             let mut error = false;
                             if !generics.params.is_empty() {
-                                let param_type = if generics.is_lt_parameterized() {
-                                    "lifetime"
-                                } else {
-                                    "type"
-                                };
-                                let msg =
-                                    format!("`main` function is not allowed to have {} parameters",
-                                            param_type);
-                                let label =
-                                    format!("`main` cannot have {} parameters", param_type);
+                                let msg = format!("`main` function is not allowed to have generic \
+                                                   parameters");
+                                let label = format!("`main` cannot have generic parameters");
                                 struct_span_err!(tcx.sess, generics.span, E0131, "{}", msg)
                                     .span_label(generics.span, label)
                                     .emit();
index 126fa7fb320348b78a3958d9a31867b86bc0729e..f0c40d1d491e21835828b5ecf4a671d91c729de1 100644 (file)
@@ -9,5 +9,5 @@ path = "lib.rs"
 
 [dependencies]
 pulldown-cmark = { version = "0.1.2", default-features = false }
-minifier = "0.0.11"
+minifier = "0.0.14"
 tempfile = "3"
index da749fca2a953524f619a2ea94286a97acd2f0c9..5c09da90491d064f6001723f0080d4e1171640e4 100644 (file)
@@ -244,34 +244,32 @@ fn get_auto_trait_impl_for<F>(
         None
     }
 
-    fn generics_to_path_params(&self, generics: ty::Generics) -> hir::PathParameters {
-        let mut lifetimes = vec![];
-        let mut types = vec![];
+    fn generics_to_path_params(&self, generics: ty::Generics) -> hir::GenericArgs {
+        let mut args = vec![];
 
         for param in generics.params.iter() {
             match param.kind {
                 ty::GenericParamDefKind::Lifetime => {
                     let name = if param.name == "" {
-                        hir::LifetimeName::Static
+                        hir::ParamName::Plain(keywords::StaticLifetime.name())
                     } else {
-                        hir::LifetimeName::Name(param.name.as_symbol())
+                        hir::ParamName::Plain(param.name.as_symbol())
                     };
 
-                    lifetimes.push(hir::Lifetime {
+                    args.push(hir::GenericArg::Lifetime(hir::Lifetime {
                         id: ast::DUMMY_NODE_ID,
                         span: DUMMY_SP,
-                        name,
-                    });
+                        name: hir::LifetimeName::Param(name),
+                    }));
                 }
                 ty::GenericParamDefKind::Type {..} => {
-                    types.push(P(self.ty_param_to_ty(param.clone())));
+                    args.push(hir::GenericArg::Type(P(self.ty_param_to_ty(param.clone()))));
                 }
             }
         }
 
-        hir::PathParameters {
-            lifetimes: HirVec::from_vec(lifetimes),
-            types: HirVec::from_vec(types),
+        hir::GenericArgs {
+            args: HirVec::from_vec(args),
             bindings: HirVec::new(),
             parenthesized: false,
         }
@@ -488,11 +486,8 @@ fn handle_lifetimes<'cx>(
             .iter()
             .flat_map(|(name, lifetime)| {
                 let empty = Vec::new();
-                let bounds: FxHashSet<Lifetime> = finished
-                    .get(name)
-                    .unwrap_or(&empty)
-                    .iter()
-                    .map(|region| self.get_lifetime(region, names_map))
+                let bounds: FxHashSet<GenericBound> = finished.get(name).unwrap_or(&empty).iter()
+                    .map(|region| GenericBound::Outlives(self.get_lifetime(region, names_map)))
                     .collect();
 
                 if bounds.is_empty() {
@@ -523,7 +518,10 @@ fn extract_for_generics<'b, 'c, 'd>(
                         // We only care about late bound regions, as we need to add them
                         // to the 'for<>' section
                         &ty::ReLateBound(_, ty::BoundRegion::BrNamed(_, name)) => {
-                            Some(GenericParamDef::Lifetime(Lifetime(name.to_string())))
+                            Some(GenericParamDef {
+                                name: name.to_string(),
+                                kind: GenericParamDefKind::Lifetime,
+                            })
                         }
                         &ty::ReVar(_) | &ty::ReEarlyBound(_) => None,
                         _ => panic!("Unexpected region type {:?}", r),
@@ -535,9 +533,9 @@ fn extract_for_generics<'b, 'c, 'd>(
 
     fn make_final_bounds<'b, 'c, 'cx>(
         &self,
-        ty_to_bounds: FxHashMap<Type, FxHashSet<TyParamBound>>,
+        ty_to_bounds: FxHashMap<Type, FxHashSet<GenericBound>>,
         ty_to_fn: FxHashMap<Type, (Option<PolyTrait>, Option<Type>)>,
-        lifetime_to_bounds: FxHashMap<Lifetime, FxHashSet<Lifetime>>,
+        lifetime_to_bounds: FxHashMap<Lifetime, FxHashSet<GenericBound>>,
     ) -> Vec<WherePredicate> {
         ty_to_bounds
             .into_iter()
@@ -555,9 +553,9 @@ fn make_final_bounds<'b, 'c, 'cx>(
                             let mut new_path = path.clone();
                             let last_segment = new_path.segments.pop().unwrap();
 
-                            let (old_input, old_output) = match last_segment.params {
-                                PathParameters::AngleBracketed { types, .. } => (types, None),
-                                PathParameters::Parenthesized { inputs, output, .. } => {
+                            let (old_input, old_output) = match last_segment.args {
+                                GenericArgs::AngleBracketed { types, .. } => (types, None),
+                                GenericArgs::Parenthesized { inputs, output, .. } => {
                                     (inputs, output)
                                 }
                             };
@@ -569,14 +567,14 @@ fn make_final_bounds<'b, 'c, 'cx>(
                                 );
                             }
 
-                            let new_params = PathParameters::Parenthesized {
+                            let new_params = GenericArgs::Parenthesized {
                                 inputs: old_input,
                                 output,
                             };
 
                             new_path.segments.push(PathSegment {
                                 name: last_segment.name,
-                                params: new_params,
+                                args: new_params,
                             });
 
                             Type::ResolvedPath {
@@ -588,7 +586,7 @@ fn make_final_bounds<'b, 'c, 'cx>(
                         }
                         _ => panic!("Unexpected data: {:?}, {:?}", ty, data),
                     };
-                    bounds.insert(TyParamBound::TraitBound(
+                    bounds.insert(GenericBound::TraitBound(
                         PolyTrait {
                             trait_: new_ty,
                             generic_params: poly_trait.generic_params,
@@ -614,7 +612,7 @@ fn make_final_bounds<'b, 'c, 'cx>(
                     .filter(|&(_, ref bounds)| !bounds.is_empty())
                     .map(|(lifetime, bounds)| {
                         let mut bounds_vec = bounds.into_iter().collect();
-                        self.sort_where_lifetimes(&mut bounds_vec);
+                        self.sort_where_bounds(&mut bounds_vec);
                         WherePredicate::RegionPredicate {
                             lifetime,
                             bounds: bounds_vec,
@@ -731,7 +729,7 @@ fn param_env_to_generics<'b, 'c, 'cx>(
                         // later
 
                         let is_fn = match &mut b {
-                            &mut TyParamBound::TraitBound(ref mut p, _) => {
+                            &mut GenericBound::TraitBound(ref mut p, _) => {
                                 // Insert regions into the for_generics hash map first, to ensure
                                 // that we don't end up with duplicate bounds (e.g. for<'b, 'b>)
                                 for_generics.extend(p.generic_params.clone());
@@ -793,13 +791,13 @@ fn param_env_to_generics<'b, 'c, 'cx>(
 
                                     // FIXME: Remove this scope when NLL lands
                                     {
-                                        let params =
-                                            &mut new_trait_path.segments.last_mut().unwrap().params;
+                                        let args =
+                                            &mut new_trait_path.segments.last_mut().unwrap().args;
 
-                                        match params {
+                                        match args {
                                             // Convert somethiung like '<T as Iterator::Item> = u8'
                                             // to 'T: Iterator<Item=u8>'
-                                            &mut PathParameters::AngleBracketed {
+                                            &mut GenericArgs::AngleBracketed {
                                                 ref mut bindings,
                                                 ..
                                             } => {
@@ -808,7 +806,7 @@ fn param_env_to_generics<'b, 'c, 'cx>(
                                                     ty: rhs,
                                                 });
                                             }
-                                            &mut PathParameters::Parenthesized { .. } => {
+                                            &mut GenericArgs::Parenthesized { .. } => {
                                                 existing_predicates.push(
                                                     WherePredicate::EqPredicate {
                                                         lhs: lhs.clone(),
@@ -825,7 +823,7 @@ fn param_env_to_generics<'b, 'c, 'cx>(
                                         .entry(*ty.clone())
                                         .or_insert_with(|| FxHashSet());
 
-                                    bounds.insert(TyParamBound::TraitBound(
+                                    bounds.insert(GenericBound::TraitBound(
                                         PolyTrait {
                                             trait_: Type::ResolvedPath {
                                                 path: new_trait_path,
@@ -842,7 +840,7 @@ fn param_env_to_generics<'b, 'c, 'cx>(
                                     // that we don't see a
                                     // duplicate bound like `T: Iterator + Iterator<Item=u8>`
                                     // on the docs page.
-                                    bounds.remove(&TyParamBound::TraitBound(
+                                    bounds.remove(&GenericBound::TraitBound(
                                         PolyTrait {
                                             trait_: *trait_.clone(),
                                             generic_params: Vec::new(),
@@ -869,19 +867,17 @@ fn param_env_to_generics<'b, 'c, 'cx>(
 
         existing_predicates.extend(final_bounds);
 
-        for p in generic_params.iter_mut() {
-            match p {
-                &mut GenericParamDef::Type(ref mut ty) => {
-                    // We never want something like 'impl<T=Foo>'
-                    ty.default.take();
-
-                    let generic_ty = Type::Generic(ty.name.clone());
-
+        for param in generic_params.iter_mut() {
+            match param.kind {
+                GenericParamDefKind::Type { ref mut default, ref mut bounds, .. } => {
+                    // We never want something like `impl<T=Foo>`.
+                    default.take();
+                    let generic_ty = Type::Generic(param.name.clone());
                     if !has_sized.contains(&generic_ty) {
-                        ty.bounds.insert(0, TyParamBound::maybe_sized(self.cx));
+                        bounds.insert(0, GenericBound::maybe_sized(self.cx));
                     }
                 }
-                GenericParamDef::Lifetime(_) => {}
+                GenericParamDefKind::Lifetime => {}
             }
         }
 
@@ -912,15 +908,7 @@ fn sort_where_predicates(&self, mut predicates: &mut Vec<WherePredicate>) {
     // both for visual consistency between 'rustdoc' runs, and to
     // make writing tests much easier
     #[inline]
-    fn sort_where_bounds(&self, mut bounds: &mut Vec<TyParamBound>) {
-        // We should never have identical bounds - and if we do,
-        // they're visually identical as well. Therefore, using
-        // an unstable sort is fine.
-        self.unstable_debug_sort(&mut bounds);
-    }
-
-    #[inline]
-    fn sort_where_lifetimes(&self, mut bounds: &mut Vec<Lifetime>) {
+    fn sort_where_bounds(&self, mut bounds: &mut Vec<GenericBound>) {
         // We should never have identical bounds - and if we do,
         // they're visually identical as well. Therefore, using
         // an unstable sort is fine.
@@ -940,7 +928,7 @@ fn sort_where_lifetimes(&self, mut bounds: &mut Vec<Lifetime>) {
     // to end users, it makes writing tests much more difficult, as predicates
     // can appear in any order in the final result.
     //
-    // To solve this problem, we sort WherePredicates and TyParamBounds
+    // To solve this problem, we sort WherePredicates and GenericBounds
     // by their Debug string. The thing to keep in mind is that we don't really
     // care what the final order is - we're synthesizing an impl or bound
     // ourselves, so any order can be considered equally valid. By sorting the
@@ -950,7 +938,7 @@ fn sort_where_lifetimes(&self, mut bounds: &mut Vec<Lifetime>) {
     // Using the Debug impementation for sorting prevents us from needing to
     // write quite a bit of almost entirely useless code (e.g. how should two
     // Types be sorted relative to each other). It also allows us to solve the
-    // problem for both WherePredicates and TyParamBounds at the same time. This
+    // problem for both WherePredicates and GenericBounds at the same time. This
     // approach is probably somewhat slower, but the small number of items
     // involved (impls rarely have more than a few bounds) means that it
     // shouldn't matter in practice.
index 80eb2d1e214fbd9146574d9ec49240a4ae8c295b..ad7389db729ec7f3151300a6ecc5f24c933a23e1 100644 (file)
@@ -198,9 +198,12 @@ fn build_external_function(cx: &DocContext, did: DefId) -> clean::Function {
     clean::Function {
         decl: (did, sig).clean(cx),
         generics: (cx.tcx.generics_of(did), &predicates).clean(cx),
-        unsafety: sig.unsafety(),
-        constness,
-        abi: sig.abi(),
+        header: hir::FnHeader {
+            unsafety: sig.unsafety(),
+            abi: sig.abi(),
+            constness,
+            asyncness: hir::IsAsync::NotAsync,
+        }
     }
 }
 
@@ -374,8 +377,8 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
     let polarity = tcx.impl_polarity(did);
     let trait_ = associated_trait.clean(cx).map(|bound| {
         match bound {
-            clean::TraitBound(polyt, _) => polyt.trait_,
-            clean::RegionBound(..) => unreachable!(),
+            clean::GenericBound::TraitBound(polyt, _) => polyt.trait_,
+            clean::GenericBound::Outlives(..) => unreachable!(),
         }
     });
     if trait_.def_id() == tcx.lang_items().deref_trait() {
@@ -387,9 +390,9 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
 
     let provided = trait_.def_id().map(|did| {
         tcx.provided_trait_methods(did)
-            .into_iter()
-            .map(|meth| meth.name.to_string())
-            .collect()
+           .into_iter()
+           .map(|meth| meth.name.to_string())
+           .collect()
     }).unwrap_or(FxHashSet());
 
     ret.push(clean::Item {
@@ -474,7 +477,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
             } if *s == "Self" => {
                 bounds.retain(|bound| {
                     match *bound {
-                        clean::TyParamBound::TraitBound(clean::PolyTrait {
+                        clean::GenericBound::TraitBound(clean::PolyTrait {
                             trait_: clean::ResolvedPath { did, .. },
                             ..
                         }, _) => did != trait_did,
@@ -505,7 +508,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
 /// the metadata for a crate, so we want to separate those out and create a new
 /// list of explicit supertrait bounds to render nicely.
 fn separate_supertrait_bounds(mut g: clean::Generics)
-                              -> (clean::Generics, Vec<clean::TyParamBound>) {
+                              -> (clean::Generics, Vec<clean::GenericBound>) {
     let mut ty_bounds = Vec::new();
     g.where_predicates.retain(|pred| {
         match *pred {
index 852a4479199df6f5f75741b421e6037aaaad771b..057e7f3ab843354d88dc3d4f15fe261cee302087 100644 (file)
 pub use self::Type::*;
 pub use self::Mutability::*;
 pub use self::ItemEnum::*;
-pub use self::TyParamBound::*;
 pub use self::SelfTy::*;
 pub use self::FunctionRetTy::*;
 pub use self::Visibility::{Public, Inherited};
 
-use syntax;
 use rustc_target::spec::abi::Abi;
+use syntax;
 use syntax::ast::{self, AttrStyle, NodeId, Ident};
 use syntax::attr;
 use syntax::codemap::{dummy_spanned, Spanned};
 use rustc::ty::fold::TypeFolder;
 use rustc::middle::lang_items;
 use rustc::mir::interpret::GlobalId;
-use rustc::hir::{self, HirVec};
+use rustc::hir::{self, GenericArg, HirVec};
 use rustc::hir::def::{self, Def, CtorKind};
 use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc::hir::def_id::DefIndexAddressSpace;
 use rustc::ty::subst::Substs;
-use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind, GenericParamCount};
+use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind};
 use rustc::middle::stability;
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
 use rustc_typeck::hir_ty_to_ty;
@@ -532,7 +531,7 @@ pub enum ItemEnum {
     MacroItem(Macro),
     PrimitiveItem(PrimitiveType),
     AssociatedConstItem(Type, Option<String>),
-    AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
+    AssociatedTypeItem(Vec<GenericBound>, Option<Type>),
     /// An item that has been stripped by a rustdoc pass
     StrippedItem(Box<ItemEnum>),
     KeywordItem(String),
@@ -1458,61 +1457,19 @@ fn clean(&self, cx: &DocContext) -> Attributes {
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
-pub struct TyParam {
-    pub name: String,
-    pub did: DefId,
-    pub bounds: Vec<TyParamBound>,
-    pub default: Option<Type>,
-    pub synthetic: Option<hir::SyntheticTyParamKind>,
-}
-
-impl Clean<TyParam> for hir::TyParam {
-    fn clean(&self, cx: &DocContext) -> TyParam {
-        TyParam {
-            name: self.name.clean(cx),
-            did: cx.tcx.hir.local_def_id(self.id),
-            bounds: self.bounds.clean(cx),
-            default: self.default.clean(cx),
-            synthetic: self.synthetic,
-        }
-    }
-}
-
-impl<'tcx> Clean<TyParam> for ty::GenericParamDef {
-    fn clean(&self, cx: &DocContext) -> TyParam {
-        cx.renderinfo.borrow_mut().external_typarams.insert(self.def_id, self.name.clean(cx));
-        let has_default = match self.kind {
-            ty::GenericParamDefKind::Type { has_default, .. } => has_default,
-            _ => panic!("tried to convert a non-type GenericParamDef as a type")
-        };
-        TyParam {
-            name: self.name.clean(cx),
-            did: self.def_id,
-            bounds: vec![], // these are filled in from the where-clauses
-            default: if has_default {
-                Some(cx.tcx.type_of(self.def_id).clean(cx))
-            } else {
-                None
-            },
-            synthetic: None,
-        }
-    }
-}
-
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
-pub enum TyParamBound {
-    RegionBound(Lifetime),
-    TraitBound(PolyTrait, hir::TraitBoundModifier)
+pub enum GenericBound {
+    TraitBound(PolyTrait, hir::TraitBoundModifier),
+    Outlives(Lifetime),
 }
 
-impl TyParamBound {
-    fn maybe_sized(cx: &DocContext) -> TyParamBound {
+impl GenericBound {
+    fn maybe_sized(cx: &DocContext) -> GenericBound {
         let did = cx.tcx.require_lang_item(lang_items::SizedTraitLangItem);
         let empty = cx.tcx.intern_substs(&[]);
         let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
             Some(did), false, vec![], empty);
         inline::record_extern_fqn(cx, did, TypeKind::Trait);
-        TraitBound(PolyTrait {
+        GenericBound::TraitBound(PolyTrait {
             trait_: ResolvedPath {
                 path,
                 typarams: None,
@@ -1525,7 +1482,7 @@ fn maybe_sized(cx: &DocContext) -> TyParamBound {
 
     fn is_sized_bound(&self, cx: &DocContext) -> bool {
         use rustc::hir::TraitBoundModifier as TBM;
-        if let TyParamBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self {
+        if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self {
             if trait_.def_id() == cx.tcx.lang_items().sized_trait() {
                 return true;
             }
@@ -1534,7 +1491,7 @@ fn is_sized_bound(&self, cx: &DocContext) -> bool {
     }
 
     fn get_poly_trait(&self) -> Option<PolyTrait> {
-        if let TyParamBound::TraitBound(ref p, _) = *self {
+        if let GenericBound::TraitBound(ref p, _) = *self {
             return Some(p.clone())
         }
         None
@@ -1542,24 +1499,26 @@ fn get_poly_trait(&self) -> Option<PolyTrait> {
 
     fn get_trait_type(&self) -> Option<Type> {
 
-        if let TyParamBound::TraitBound(PolyTrait { ref trait_, .. }, _) = *self {
+        if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, _) = *self {
             return Some(trait_.clone());
         }
         None
     }
 }
 
-impl Clean<TyParamBound> for hir::TyParamBound {
-    fn clean(&self, cx: &DocContext) -> TyParamBound {
+impl Clean<GenericBound> for hir::GenericBound {
+    fn clean(&self, cx: &DocContext) -> GenericBound {
         match *self {
-            hir::RegionTyParamBound(lt) => RegionBound(lt.clean(cx)),
-            hir::TraitTyParamBound(ref t, modifier) => TraitBound(t.clean(cx), modifier),
+            hir::GenericBound::Outlives(lt) => GenericBound::Outlives(lt.clean(cx)),
+            hir::GenericBound::Trait(ref t, modifier) => {
+                GenericBound::TraitBound(t.clean(cx), modifier)
+            }
         }
     }
 }
 
-fn external_path_params(cx: &DocContext, trait_did: Option<DefId>, has_self: bool,
-                        bindings: Vec<TypeBinding>, substs: &Substs) -> PathParameters {
+fn external_generic_args(cx: &DocContext, trait_did: Option<DefId>, has_self: bool,
+                        bindings: Vec<TypeBinding>, substs: &Substs) -> GenericArgs {
     let lifetimes = substs.regions().filter_map(|v| v.clean(cx)).collect();
     let types = substs.types().skip(has_self as usize).collect::<Vec<_>>();
 
@@ -1570,7 +1529,7 @@ fn external_path_params(cx: &DocContext, trait_did: Option<DefId>, has_self: boo
             let inputs = match types[0].sty {
                 ty::TyTuple(ref tys) => tys.iter().map(|t| t.clean(cx)).collect(),
                 _ => {
-                    return PathParameters::AngleBracketed {
+                    return GenericArgs::AngleBracketed {
                         lifetimes,
                         types: types.clean(cx),
                         bindings,
@@ -1583,13 +1542,13 @@ fn external_path_params(cx: &DocContext, trait_did: Option<DefId>, has_self: boo
             //     ty::TyTuple(ref v) if v.is_empty() => None, // -> ()
             //     _ => Some(types[1].clean(cx))
             // };
-            PathParameters::Parenthesized {
+            GenericArgs::Parenthesized {
                 inputs,
                 output,
             }
         },
         _ => {
-            PathParameters::AngleBracketed {
+            GenericArgs::AngleBracketed {
                 lifetimes,
                 types: types.clean(cx),
                 bindings,
@@ -1607,13 +1566,13 @@ fn external_path(cx: &DocContext, name: &str, trait_did: Option<DefId>, has_self
         def: Def::Err,
         segments: vec![PathSegment {
             name: name.to_string(),
-            params: external_path_params(cx, trait_did, has_self, bindings, substs)
+            args: external_generic_args(cx, trait_did, has_self, bindings, substs)
         }],
     }
 }
 
-impl<'a, 'tcx> Clean<TyParamBound> for (&'a ty::TraitRef<'tcx>, Vec<TypeBinding>) {
-    fn clean(&self, cx: &DocContext) -> TyParamBound {
+impl<'a, 'tcx> Clean<GenericBound> for (&'a ty::TraitRef<'tcx>, Vec<TypeBinding>) {
+    fn clean(&self, cx: &DocContext) -> GenericBound {
         let (trait_ref, ref bounds) = *self;
         inline::record_extern_fqn(cx, trait_ref.def_id, TypeKind::Trait);
         let path = external_path(cx, &cx.tcx.item_name(trait_ref.def_id).as_str(),
@@ -1629,8 +1588,11 @@ fn clean(&self, cx: &DocContext) -> TyParamBound {
                     if let ty::TyRef(ref reg, _, _) = ty_s.sty {
                         if let &ty::RegionKind::ReLateBound(..) = *reg {
                             debug!("  hit an ReLateBound {:?}", reg);
-                            if let Some(lt) = reg.clean(cx) {
-                                late_bounds.push(GenericParamDef::Lifetime(lt));
+                            if let Some(Lifetime(name)) = reg.clean(cx) {
+                                late_bounds.push(GenericParamDef {
+                                    name,
+                                    kind: GenericParamDefKind::Lifetime,
+                                });
                             }
                         }
                     }
@@ -1638,7 +1600,7 @@ fn clean(&self, cx: &DocContext) -> TyParamBound {
             }
         }
 
-        TraitBound(
+        GenericBound::TraitBound(
             PolyTrait {
                 trait_: ResolvedPath {
                     path,
@@ -1653,18 +1615,17 @@ fn clean(&self, cx: &DocContext) -> TyParamBound {
     }
 }
 
-impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
-    fn clean(&self, cx: &DocContext) -> TyParamBound {
+impl<'tcx> Clean<GenericBound> for ty::TraitRef<'tcx> {
+    fn clean(&self, cx: &DocContext) -> GenericBound {
         (self, vec![]).clean(cx)
     }
 }
 
-impl<'tcx> Clean<Option<Vec<TyParamBound>>> for Substs<'tcx> {
-    fn clean(&self, cx: &DocContext) -> Option<Vec<TyParamBound>> {
+impl<'tcx> Clean<Option<Vec<GenericBound>>> for Substs<'tcx> {
+    fn clean(&self, cx: &DocContext) -> Option<Vec<GenericBound>> {
         let mut v = Vec::new();
-        v.extend(self.regions().filter_map(|r| r.clean(cx))
-                     .map(RegionBound));
-        v.extend(self.types().map(|t| TraitBound(PolyTrait {
+        v.extend(self.regions().filter_map(|r| r.clean(cx)).map(GenericBound::Outlives));
+        v.extend(self.types().map(|t| GenericBound::TraitBound(PolyTrait {
             trait_: t.clean(cx),
             generic_params: Vec::new(),
         }, hir::TraitBoundModifier::None)));
@@ -1707,18 +1668,26 @@ fn clean(&self, cx: &DocContext) -> Lifetime {
     }
 }
 
-impl Clean<Lifetime> for hir::LifetimeDef {
+impl Clean<Lifetime> for hir::GenericParam {
     fn clean(&self, _: &DocContext) -> Lifetime {
-        if self.bounds.len() > 0 {
-            let mut s = format!("{}: {}",
-                                self.lifetime.name.name(),
-                                self.bounds[0].name.name());
-            for bound in self.bounds.iter().skip(1) {
-                s.push_str(&format!(" + {}", bound.name.name()));
+        match self.kind {
+            hir::GenericParamKind::Lifetime { .. } => {
+                if self.bounds.len() > 0 {
+                    let mut bounds = self.bounds.iter().map(|bound| match bound {
+                        hir::GenericBound::Outlives(lt) => lt,
+                        _ => panic!(),
+                    });
+                    let name = bounds.next().unwrap().name.name();
+                    let mut s = format!("{}: {}", self.name.name(), name);
+                    for bound in bounds {
+                        s.push_str(&format!(" + {}", bound.name.name()));
+                    }
+                    Lifetime(s)
+                } else {
+                    Lifetime(self.name.name().to_string())
+                }
             }
-            Lifetime(s)
-        } else {
-            Lifetime(self.lifetime.name.name().to_string())
+            _ => panic!(),
         }
     }
 }
@@ -1751,8 +1720,8 @@ fn clean(&self, cx: &DocContext) -> Option<Lifetime> {
 
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
 pub enum WherePredicate {
-    BoundPredicate { ty: Type, bounds: Vec<TyParamBound> },
-    RegionPredicate { lifetime: Lifetime, bounds: Vec<Lifetime>},
+    BoundPredicate { ty: Type, bounds: Vec<GenericBound> },
+    RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
     EqPredicate { lhs: Type, rhs: Type },
 }
 
@@ -1822,7 +1791,7 @@ fn clean(&self, cx: &DocContext) -> WherePredicate {
         let ty::OutlivesPredicate(ref a, ref b) = *self;
         WherePredicate::RegionPredicate {
             lifetime: a.clean(cx).unwrap(),
-            bounds: vec![b.clean(cx).unwrap()]
+            bounds: vec![GenericBound::Outlives(b.clean(cx).unwrap())]
         }
     }
 }
@@ -1833,7 +1802,7 @@ fn clean(&self, cx: &DocContext) -> WherePredicate {
 
         WherePredicate::BoundPredicate {
             ty: ty.clean(cx),
-            bounds: vec![TyParamBound::RegionBound(lt.clean(cx).unwrap())]
+            bounds: vec![GenericBound::Outlives(lt.clean(cx).unwrap())]
         }
     }
 }
@@ -1850,10 +1819,8 @@ fn clean(&self, cx: &DocContext) -> WherePredicate {
 impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
     fn clean(&self, cx: &DocContext) -> Type {
         let trait_ = match self.trait_ref(cx.tcx).clean(cx) {
-            TyParamBound::TraitBound(t, _) => t.trait_,
-            TyParamBound::RegionBound(_) => {
-                panic!("cleaning a trait got a region")
-            }
+            GenericBound::TraitBound(t, _) => t.trait_,
+            GenericBound::Outlives(_) => panic!("cleaning a trait got a lifetime"),
         };
         Type::QPath {
             name: cx.tcx.associated_item(self.item_def_id).name.clean(cx),
@@ -1864,25 +1831,95 @@ fn clean(&self, cx: &DocContext) -> Type {
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
-pub enum GenericParamDef {
-    Lifetime(Lifetime),
-    Type(TyParam),
+pub enum GenericParamDefKind {
+    Lifetime,
+    Type {
+        did: DefId,
+        bounds: Vec<GenericBound>,
+        default: Option<Type>,
+        synthetic: Option<hir::SyntheticTyParamKind>,
+    },
+}
+
+#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+pub struct GenericParamDef {
+    pub name: String,
+
+    pub kind: GenericParamDefKind,
 }
 
 impl GenericParamDef {
     pub fn is_synthetic_type_param(&self) -> bool {
-        match self {
-            GenericParamDef::Type(ty) => ty.synthetic.is_some(),
-            GenericParamDef::Lifetime(_) => false,
+        match self.kind {
+            GenericParamDefKind::Lifetime => false,
+            GenericParamDefKind::Type { ref synthetic, .. } => synthetic.is_some(),
+        }
+    }
+}
+
+impl<'tcx> Clean<GenericParamDef> for ty::GenericParamDef {
+    fn clean(&self, cx: &DocContext) -> GenericParamDef {
+        let (name, kind) = match self.kind {
+            ty::GenericParamDefKind::Lifetime => {
+                (self.name.to_string(), GenericParamDefKind::Lifetime)
+            }
+            ty::GenericParamDefKind::Type { has_default, .. } => {
+                cx.renderinfo.borrow_mut().external_typarams
+                             .insert(self.def_id, self.name.clean(cx));
+                let default = if has_default {
+                    Some(cx.tcx.type_of(self.def_id).clean(cx))
+                } else {
+                    None
+                };
+                (self.name.clean(cx), GenericParamDefKind::Type {
+                    did: self.def_id,
+                    bounds: vec![], // These are filled in from the where-clauses.
+                    default,
+                    synthetic: None,
+                })
+            }
+        };
+
+        GenericParamDef {
+            name,
+            kind,
         }
     }
 }
 
 impl Clean<GenericParamDef> for hir::GenericParam {
     fn clean(&self, cx: &DocContext) -> GenericParamDef {
-        match *self {
-            hir::GenericParam::Lifetime(ref l) => GenericParamDef::Lifetime(l.clean(cx)),
-            hir::GenericParam::Type(ref t) => GenericParamDef::Type(t.clean(cx)),
+        let (name, kind) = match self.kind {
+            hir::GenericParamKind::Lifetime { .. } => {
+                let name = if self.bounds.len() > 0 {
+                    let mut bounds = self.bounds.iter().map(|bound| match bound {
+                        hir::GenericBound::Outlives(lt) => lt,
+                        _ => panic!(),
+                    });
+                    let name = bounds.next().unwrap().name.name();
+                    let mut s = format!("{}: {}", self.name.name(), name);
+                    for bound in bounds {
+                        s.push_str(&format!(" + {}", bound.name.name()));
+                    }
+                    s
+                } else {
+                    self.name.name().to_string()
+                };
+                (name, GenericParamDefKind::Lifetime)
+            }
+            hir::GenericParamKind::Type { ref default, synthetic, .. } => {
+                (self.name.name().clean(cx), GenericParamDefKind::Type {
+                    did: cx.tcx.hir.local_def_id(self.id),
+                    bounds: self.bounds.clean(cx),
+                    default: default.clean(cx),
+                    synthetic: synthetic,
+                })
+            }
+        };
+
+        GenericParamDef {
+            name,
+            kind,
         }
     }
 }
@@ -1900,25 +1937,25 @@ fn clean(&self, cx: &DocContext) -> Generics {
         // In order for normal parameters to be able to refer to synthetic ones,
         // scans them first.
         fn is_impl_trait(param: &hir::GenericParam) -> bool {
-            if let hir::GenericParam::Type(ref tp) = param {
-                tp.synthetic == Some(hir::SyntheticTyParamKind::ImplTrait)
-            } else {
-                false
+            match param.kind {
+                hir::GenericParamKind::Type { synthetic, .. } => {
+                    synthetic == Some(hir::SyntheticTyParamKind::ImplTrait)
+                }
+                _ => false,
             }
         }
         let impl_trait_params = self.params
             .iter()
-            .filter(|p| is_impl_trait(p))
-            .map(|p| {
-                let p = p.clean(cx);
-                if let GenericParamDef::Type(ref tp) = p {
-                    cx.impl_trait_bounds
-                        .borrow_mut()
-                        .insert(tp.did, tp.bounds.clone());
-                } else {
-                    unreachable!()
+            .filter(|param| is_impl_trait(param))
+            .map(|param| {
+                let param: GenericParamDef = param.clean(cx);
+                match param.kind {
+                    GenericParamDefKind::Lifetime => unreachable!(),
+                    GenericParamDefKind::Type { did, ref bounds, .. } => {
+                        cx.impl_trait_bounds.borrow_mut().insert(did, bounds.clone());
+                    }
                 }
-                p
+                param
             })
             .collect::<Vec<_>>();
 
@@ -1929,23 +1966,26 @@ fn is_impl_trait(param: &hir::GenericParam) -> bool {
         }
         params.extend(impl_trait_params);
 
-        let mut g = Generics {
+        let mut generics = Generics {
             params,
-            where_predicates: self.where_clause.predicates.clean(cx)
+            where_predicates: self.where_clause.predicates.clean(cx),
         };
 
         // Some duplicates are generated for ?Sized bounds between type params and where
         // predicates. The point in here is to move the bounds definitions from type params
         // to where predicates when such cases occur.
-        for where_pred in &mut g.where_predicates {
+        for where_pred in &mut generics.where_predicates {
             match *where_pred {
                 WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds } => {
                     if bounds.is_empty() {
-                        for param in &mut g.params {
-                            if let GenericParamDef::Type(ref mut type_param) = *param {
-                                if &type_param.name == name {
-                                    mem::swap(bounds, &mut type_param.bounds);
-                                    break
+                        for param in &mut generics.params {
+                            match param.kind {
+                                GenericParamDefKind::Lifetime => {}
+                                GenericParamDefKind::Type { bounds: ref mut ty_bounds, .. } => {
+                                    if &param.name == name {
+                                        mem::swap(bounds, ty_bounds);
+                                        break
+                                    }
                                 }
                             }
                         }
@@ -1954,7 +1994,7 @@ fn is_impl_trait(param: &hir::GenericParam) -> bool {
                 _ => continue,
             }
         }
-        g
+        generics
     }
 }
 
@@ -1968,18 +2008,16 @@ fn clean(&self, cx: &DocContext) -> Generics {
         // Bounds in the type_params and lifetimes fields are repeated in the
         // predicates field (see rustc_typeck::collect::ty_generics), so remove
         // them.
-        let stripped_typarams = gens.params.iter().filter_map(|param| {
-            if let ty::GenericParamDefKind::Type {..} = param.kind {
+        let stripped_typarams = gens.params.iter().filter_map(|param| match param.kind {
+            ty::GenericParamDefKind::Lifetime => None,
+            ty::GenericParamDefKind::Type { .. } => {
                 if param.name == keywords::SelfType.name().as_str() {
                     assert_eq!(param.index, 0);
-                    None
-                } else {
-                    Some(param.clean(cx))
+                    return None;
                 }
-            } else {
-                None
+                Some(param.clean(cx))
             }
-        }).collect::<Vec<TyParam>>();
+        }).collect::<Vec<GenericParamDef>>();
 
         let mut where_predicates = preds.predicates.to_vec().clean(cx);
 
@@ -2011,7 +2049,7 @@ fn clean(&self, cx: &DocContext) -> Generics {
             if !sized_params.contains(&tp.name) {
                 where_predicates.push(WP::BoundPredicate {
                     ty: Type::Generic(tp.name.clone()),
-                    bounds: vec![TyParamBound::maybe_sized(cx)],
+                    bounds: vec![GenericBound::maybe_sized(cx)],
                 })
             }
         }
@@ -2023,17 +2061,10 @@ fn clean(&self, cx: &DocContext) -> Generics {
         Generics {
             params: gens.params
                         .iter()
-                        .flat_map(|param| {
-                            if let ty::GenericParamDefKind::Lifetime = param.kind {
-                                Some(GenericParamDef::Lifetime(param.clean(cx)))
-                            } else {
-                                None
-                            }
-                        }).chain(
-                            simplify::ty_params(stripped_typarams)
-                                .into_iter()
-                                .map(|tp| GenericParamDef::Type(tp))
-                        )
+                        .flat_map(|param| match param.kind {
+                            ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)),
+                            ty::GenericParamDefKind::Type { .. } => None,
+                        }).chain(simplify::ty_params(stripped_typarams).into_iter())
                         .collect(),
             where_predicates: simplify::where_clauses(cx, where_predicates),
         }
@@ -2043,10 +2074,8 @@ fn clean(&self, cx: &DocContext) -> Generics {
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Method {
     pub generics: Generics,
-    pub unsafety: hir::Unsafety,
-    pub constness: hir::Constness,
     pub decl: FnDecl,
-    pub abi: Abi,
+    pub header: hir::FnHeader,
 }
 
 impl<'a> Clean<Method> for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId) {
@@ -2057,28 +2086,23 @@ fn clean(&self, cx: &DocContext) -> Method {
         Method {
             decl,
             generics,
-            unsafety: self.0.unsafety,
-            constness: self.0.constness,
-            abi: self.0.abi
+            header: self.0.header,
         }
     }
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct TyMethod {
-    pub unsafety: hir::Unsafety,
+    pub header: hir::FnHeader,
     pub decl: FnDecl,
     pub generics: Generics,
-    pub abi: Abi,
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Function {
     pub decl: FnDecl,
     pub generics: Generics,
-    pub unsafety: hir::Unsafety,
-    pub constness: hir::Constness,
-    pub abi: Abi,
+    pub header: hir::FnHeader,
 }
 
 impl Clean<Item> for doctree::Function {
@@ -2097,9 +2121,7 @@ fn clean(&self, cx: &DocContext) -> Item {
             inner: FunctionItem(Function {
                 decl,
                 generics,
-                unsafety: self.unsafety,
-                constness: self.constness,
-                abi: self.abi,
+                header: self.header,
             }),
         }
     }
@@ -2259,7 +2281,7 @@ pub struct Trait {
     pub unsafety: hir::Unsafety,
     pub items: Vec<Item>,
     pub generics: Generics,
-    pub bounds: Vec<TyParamBound>,
+    pub bounds: Vec<GenericBound>,
     pub is_spotlight: bool,
     pub is_auto: bool,
 }
@@ -2328,10 +2350,9 @@ fn clean(&self, cx: &DocContext) -> Item {
                     (self.generics.clean(cx), (&*sig.decl, &names[..]).clean(cx))
                 });
                 TyMethodItem(TyMethod {
-                    unsafety: sig.unsafety.clone(),
+                    header: sig.header,
                     decl,
                     generics,
-                    abi: sig.abi
                 })
             }
             hir::TraitItemKind::Type(ref bounds, ref default) => {
@@ -2430,18 +2451,25 @@ fn clean(&self, cx: &DocContext) -> Item {
                         hir::Constness::NotConst
                     };
                     MethodItem(Method {
-                        unsafety: sig.unsafety(),
                         generics,
                         decl,
-                        abi: sig.abi(),
-                        constness,
+                        header: hir::FnHeader {
+                            unsafety: sig.unsafety(),
+                            abi: sig.abi(),
+                            constness,
+                            asyncness: hir::IsAsync::NotAsync,
+                        }
                     })
                 } else {
                     TyMethodItem(TyMethod {
-                        unsafety: sig.unsafety(),
                         generics,
                         decl,
-                        abi: sig.abi(),
+                        header: hir::FnHeader {
+                            unsafety: sig.unsafety(),
+                            abi: sig.abi(),
+                            constness: hir::Constness::NotConst,
+                            asyncness: hir::IsAsync::NotAsync,
+                        }
                     })
                 }
             }
@@ -2481,7 +2509,7 @@ fn clean(&self, cx: &DocContext) -> Item {
                     // at the end.
                     match bounds.iter().position(|b| b.is_sized_bound(cx)) {
                         Some(i) => { bounds.remove(i); }
-                        None => bounds.push(TyParamBound::maybe_sized(cx)),
+                        None => bounds.push(GenericBound::maybe_sized(cx)),
                     }
 
                     let ty = if self.defaultness.has_value() {
@@ -2536,7 +2564,7 @@ pub enum Type {
     /// structs/enums/traits (most that'd be an hir::TyPath)
     ResolvedPath {
         path: Path,
-        typarams: Option<Vec<TyParamBound>>,
+        typarams: Option<Vec<GenericBound>>,
         did: DefId,
         /// true if is a `T::Name` path for associated types
         is_generic: bool,
@@ -2572,7 +2600,7 @@ pub enum Type {
     Infer,
 
     // impl TraitA+TraitB
-    ImplTrait(Vec<TyParamBound>),
+    ImplTrait(Vec<GenericBound>),
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Copy, Debug)]
@@ -2656,7 +2684,7 @@ pub fn generics(&self) -> Option<&[Type]> {
         match *self {
             ResolvedPath { ref path, .. } => {
                 path.segments.last().and_then(|seg| {
-                    if let PathParameters::AngleBracketed { ref types, .. } = seg.params {
+                    if let GenericArgs::AngleBracketed { ref types, .. } = seg.args {
                         Some(&**types)
                     } else {
                         None
@@ -2851,31 +2879,55 @@ fn clean(&self, cx: &DocContext) -> Type {
                     let provided_params = &path.segments.last().unwrap();
                     let mut ty_substs = FxHashMap();
                     let mut lt_substs = FxHashMap();
-                    provided_params.with_parameters(|provided_params| {
-                        let mut indices = GenericParamCount {
+                    provided_params.with_generic_args(|generic_args| {
+                        let mut indices = ty::GenericParamCount {
                             lifetimes: 0,
                             types: 0
                         };
                         for param in generics.params.iter() {
-                            match param {
-                                hir::GenericParam::Lifetime(lt_param) => {
-                                    if let Some(lt) = provided_params.lifetimes
-                                        .get(indices.lifetimes).cloned() {
+                            match param.kind {
+                                hir::GenericParamKind::Lifetime { .. } => {
+                                    let mut j = 0;
+                                    let lifetime = generic_args.args.iter().find_map(|arg| {
+                                        match arg {
+                                            GenericArg::Lifetime(lt) => {
+                                                if indices.lifetimes == j {
+                                                    return Some(lt);
+                                                }
+                                                j += 1;
+                                                None
+                                            }
+                                            _ => None,
+                                        }
+                                    });
+                                    if let Some(lt) = lifetime.cloned() {
                                         if !lt.is_elided() {
                                             let lt_def_id =
-                                                cx.tcx.hir.local_def_id(lt_param.lifetime.id);
+                                                cx.tcx.hir.local_def_id(param.id);
                                             lt_substs.insert(lt_def_id, lt.clean(cx));
                                         }
                                     }
                                     indices.lifetimes += 1;
                                 }
-                                hir::GenericParam::Type(ty_param) => {
+                                hir::GenericParamKind::Type { ref default, .. } => {
                                     let ty_param_def =
-                                        Def::TyParam(cx.tcx.hir.local_def_id(ty_param.id));
-                                    if let Some(ty) = provided_params.types
-                                        .get(indices.types).cloned() {
+                                        Def::TyParam(cx.tcx.hir.local_def_id(param.id));
+                                    let mut j = 0;
+                                    let type_ = generic_args.args.iter().find_map(|arg| {
+                                        match arg {
+                                            GenericArg::Type(ty) => {
+                                                if indices.types == j {
+                                                    return Some(ty);
+                                                }
+                                                j += 1;
+                                                None
+                                            }
+                                            _ => None,
+                                        }
+                                    });
+                                    if let Some(ty) = type_.cloned() {
                                         ty_substs.insert(ty_param_def, ty.into_inner().clean(cx));
-                                    } else if let Some(default) = ty_param.default.clone() {
+                                    } else if let Some(default) = default.clone() {
                                         ty_substs.insert(ty_param_def,
                                                          default.into_inner().clean(cx));
                                     }
@@ -2922,18 +2974,14 @@ fn clean(&self, cx: &DocContext) -> Type {
             TyTraitObject(ref bounds, ref lifetime) => {
                 match bounds[0].clean(cx).trait_ {
                     ResolvedPath { path, typarams: None, did, is_generic } => {
-                        let mut bounds: Vec<_> = bounds[1..].iter().map(|bound| {
-                            TraitBound(bound.clean(cx), hir::TraitBoundModifier::None)
+                        let mut bounds: Vec<self::GenericBound> = bounds[1..].iter().map(|bound| {
+                            self::GenericBound::TraitBound(bound.clean(cx),
+                                                           hir::TraitBoundModifier::None)
                         }).collect();
                         if !lifetime.is_elided() {
-                            bounds.push(RegionBound(lifetime.clean(cx)));
-                        }
-                        ResolvedPath {
-                            path,
-                            typarams: Some(bounds),
-                            did,
-                            is_generic,
+                            bounds.push(self::GenericBound::Outlives(lifetime.clean(cx)));
                         }
+                        ResolvedPath { path, typarams: Some(bounds), did, is_generic, }
                     }
                     _ => Infer // shouldn't happen
                 }
@@ -3030,13 +3078,13 @@ fn clean(&self, cx: &DocContext) -> Type {
                     inline::record_extern_fqn(cx, did, TypeKind::Trait);
 
                     let mut typarams = vec![];
-                    reg.clean(cx).map(|b| typarams.push(RegionBound(b)));
+                    reg.clean(cx).map(|b| typarams.push(GenericBound::Outlives(b)));
                     for did in obj.auto_traits() {
                         let empty = cx.tcx.intern_substs(&[]);
                         let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
                             Some(did), false, vec![], empty);
                         inline::record_extern_fqn(cx, did, TypeKind::Trait);
-                        let bound = TraitBound(PolyTrait {
+                        let bound = GenericBound::TraitBound(PolyTrait {
                             trait_: ResolvedPath {
                                 path,
                                 typarams: None,
@@ -3087,7 +3135,9 @@ fn clean(&self, cx: &DocContext) -> Type {
                         tr
                     } else if let ty::Predicate::TypeOutlives(pred) = *predicate {
                         // these should turn up at the end
-                        pred.skip_binder().1.clean(cx).map(|r| regions.push(RegionBound(r)));
+                        pred.skip_binder().1.clean(cx).map(|r| {
+                            regions.push(GenericBound::Outlives(r))
+                        });
                         return None;
                     } else {
                         return None;
@@ -3100,7 +3150,6 @@ fn clean(&self, cx: &DocContext) -> Type {
                         }
                     }
 
-
                     let bounds = bounds.predicates.iter().filter_map(|pred|
                         if let ty::Predicate::Projection(proj) = *pred {
                             let proj = proj.skip_binder();
@@ -3122,7 +3171,7 @@ fn clean(&self, cx: &DocContext) -> Type {
                 }).collect::<Vec<_>>();
                 bounds.extend(regions);
                 if !has_sized && !bounds.is_empty() {
-                    bounds.insert(0, TyParamBound::maybe_sized(cx));
+                    bounds.insert(0, GenericBound::maybe_sized(cx));
                 }
                 ImplTrait(bounds)
             }
@@ -3447,7 +3496,7 @@ pub fn singleton(name: String) -> Path {
             def: Def::Err,
             segments: vec![PathSegment {
                 name,
-                params: PathParameters::AngleBracketed {
+                args: GenericArgs::AngleBracketed {
                     lifetimes: Vec::new(),
                     types: Vec::new(),
                     bindings: Vec::new(),
@@ -3472,7 +3521,7 @@ fn clean(&self, cx: &DocContext) -> Path {
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
-pub enum PathParameters {
+pub enum GenericArgs {
     AngleBracketed {
         lifetimes: Vec<Lifetime>,
         types: Vec<Type>,
@@ -3484,22 +3533,33 @@ pub enum PathParameters {
     }
 }
 
-impl Clean<PathParameters> for hir::PathParameters {
-    fn clean(&self, cx: &DocContext) -> PathParameters {
+impl Clean<GenericArgs> for hir::GenericArgs {
+    fn clean(&self, cx: &DocContext) -> GenericArgs {
         if self.parenthesized {
             let output = self.bindings[0].ty.clean(cx);
-            PathParameters::Parenthesized {
+            GenericArgs::Parenthesized {
                 inputs: self.inputs().clean(cx),
                 output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None }
             }
         } else {
-            PathParameters::AngleBracketed {
-                lifetimes: if self.lifetimes.iter().all(|lt| lt.is_elided()) {
-                    vec![]
-                } else {
-                    self.lifetimes.clean(cx)
-                },
-                types: self.types.clean(cx),
+            let (mut lifetimes, mut types) = (vec![], vec![]);
+            let mut elided_lifetimes = true;
+            for arg in &self.args {
+                match arg {
+                    GenericArg::Lifetime(lt) => {
+                        if !lt.is_elided() {
+                            elided_lifetimes = false;
+                        }
+                        lifetimes.push(lt.clean(cx));
+                    }
+                    GenericArg::Type(ty) => {
+                        types.push(ty.clean(cx));
+                    }
+                }
+            }
+            GenericArgs::AngleBracketed {
+                lifetimes: if elided_lifetimes { vec![] } else { lifetimes },
+                types,
                 bindings: self.bindings.clean(cx),
             }
         }
@@ -3509,14 +3569,14 @@ fn clean(&self, cx: &DocContext) -> PathParameters {
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
 pub struct PathSegment {
     pub name: String,
-    pub params: PathParameters,
+    pub args: GenericArgs,
 }
 
 impl Clean<PathSegment> for hir::PathSegment {
     fn clean(&self, cx: &DocContext) -> PathSegment {
         PathSegment {
             name: self.name.clean(cx),
-            params: self.with_parameters(|parameters| parameters.clean(cx))
+            args: self.with_generic_args(|generic_args| generic_args.clean(cx))
         }
     }
 }
@@ -3550,7 +3610,7 @@ fn strip_path(path: &Path) -> Path {
     let segments = path.segments.iter().map(|s| {
         PathSegment {
             name: s.name.clone(),
-            params: PathParameters::AngleBracketed {
+            args: GenericArgs::AngleBracketed {
                 lifetimes: Vec::new(),
                 types: Vec::new(),
                 bindings: Vec::new(),
@@ -3634,9 +3694,9 @@ fn clean(&self, cx: &DocContext) -> BareFunctionDecl {
         });
         BareFunctionDecl {
             unsafety: self.unsafety,
+            abi: self.abi,
             decl,
             generic_params,
-            abi: self.abi,
         }
     }
 }
@@ -3931,7 +3991,7 @@ fn clean(&self, cx: &DocContext) -> Vec<Item> {
         let mut items = self.items.clean(cx);
         for item in &mut items {
             if let ForeignFunctionItem(ref mut f) = item.inner {
-                f.abi = self.abi;
+                f.header.abi = self.abi;
             }
         }
         items
@@ -3948,9 +4008,12 @@ fn clean(&self, cx: &DocContext) -> Item {
                 ForeignFunctionItem(Function {
                     decl,
                     generics,
-                    unsafety: hir::Unsafety::Unsafe,
-                    abi: Abi::Rust,
-                    constness: hir::Constness::NotConst,
+                    header: hir::FnHeader {
+                        unsafety: hir::Unsafety::Unsafe,
+                        abi: Abi::Rust,
+                        constness: hir::Constness::NotConst,
+                        asyncness: hir::IsAsync::NotAsync,
+                    },
                 })
             }
             hir::ForeignItemStatic(ref ty, mutbl) => {
@@ -4365,7 +4428,7 @@ fn push(&mut self, text: &str) {
         def: def_ctor(def_id),
         segments: hir::HirVec::from_vec(apb.names.iter().map(|s| hir::PathSegment {
             name: ast::Name::intern(&s),
-            parameters: None,
+            args: None,
             infer_types: false,
         }).collect())
     }
@@ -4388,8 +4451,8 @@ struct RegionDeps<'tcx> {
 
 #[derive(Eq, PartialEq, Hash, Debug)]
 enum SimpleBound {
-    RegionBound(Lifetime),
-    TraitBound(Vec<PathSegment>, Vec<SimpleBound>, Vec<GenericParamDef>, hir::TraitBoundModifier)
+    TraitBound(Vec<PathSegment>, Vec<SimpleBound>, Vec<GenericParamDef>, hir::TraitBoundModifier),
+    Outlives(Lifetime),
 }
 
 enum AutoTraitResult {
@@ -4407,11 +4470,11 @@ fn is_auto(&self) -> bool {
     }
 }
 
-impl From<TyParamBound> for SimpleBound {
-    fn from(bound: TyParamBound) -> Self {
+impl From<GenericBound> for SimpleBound {
+    fn from(bound: GenericBound) -> Self {
         match bound.clone() {
-            TyParamBound::RegionBound(l) => SimpleBound::RegionBound(l),
-            TyParamBound::TraitBound(t, mod_) => match t.trait_ {
+            GenericBound::Outlives(l) => SimpleBound::Outlives(l),
+            GenericBound::TraitBound(t, mod_) => match t.trait_ {
                 Type::ResolvedPath { path, typarams, .. } => {
                     SimpleBound::TraitBound(path.segments,
                                             typarams
index b7767606a6aa48861602c9b81f7e2c10d19088db..30a55bf0d18092f112df492ec5356e51f01bf1bb 100644 (file)
@@ -27,7 +27,7 @@
 use rustc::hir::def_id::DefId;
 use rustc::ty;
 
-use clean::PathParameters as PP;
+use clean::GenericArgs as PP;
 use clean::WherePredicate as WP;
 use clean;
 use core::DocContext;
@@ -83,8 +83,8 @@ pub fn where_clauses(cx: &DocContext, clauses: Vec<WP>) -> Vec<WP> {
         };
         !bounds.iter_mut().any(|b| {
             let trait_ref = match *b {
-                clean::TraitBound(ref mut tr, _) => tr,
-                clean::RegionBound(..) => return false,
+                clean::GenericBound::TraitBound(ref mut tr, _) => tr,
+                clean::GenericBound::Outlives(..) => return false,
             };
             let (did, path) = match trait_ref.trait_ {
                 clean::ResolvedPath { did, ref mut path, ..} => (did, path),
@@ -97,7 +97,7 @@ pub fn where_clauses(cx: &DocContext, clauses: Vec<WP>) -> Vec<WP> {
                 return false
             }
             let last = path.segments.last_mut().unwrap();
-            match last.params {
+            match last.args {
                 PP::AngleBracketed { ref mut bindings, .. } => {
                     bindings.push(clean::TypeBinding {
                         name: name.clone(),
@@ -135,14 +135,19 @@ pub fn where_clauses(cx: &DocContext, clauses: Vec<WP>) -> Vec<WP> {
     clauses
 }
 
-pub fn ty_params(mut params: Vec<clean::TyParam>) -> Vec<clean::TyParam> {
+pub fn ty_params(mut params: Vec<clean::GenericParamDef>) -> Vec<clean::GenericParamDef> {
     for param in &mut params {
-        param.bounds = ty_bounds(mem::replace(&mut param.bounds, Vec::new()));
+        match param.kind {
+            clean::GenericParamDefKind::Type { ref mut bounds, .. } => {
+                *bounds = ty_bounds(mem::replace(bounds, Vec::new()));
+            }
+            _ => panic!("expected only type parameters"),
+        }
     }
     params
 }
 
-fn ty_bounds(bounds: Vec<clean::TyParamBound>) -> Vec<clean::TyParamBound> {
+fn ty_bounds(bounds: Vec<clean::GenericBound>) -> Vec<clean::GenericBound> {
     bounds
 }
 
index 2d71b48d8ac1e309a9a4e7c5c3d82d8b5c2ebba6..ddc9bdb384c0b359812661b4ac37058adeae0578 100644 (file)
@@ -77,7 +77,7 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> {
     /// Table node id of lifetime parameter definition -> substituted lifetime
     pub lt_substs: RefCell<FxHashMap<DefId, clean::Lifetime>>,
     /// Table DefId of `impl Trait` in argument position -> bounds
-    pub impl_trait_bounds: RefCell<FxHashMap<DefId, Vec<clean::TyParamBound>>>,
+    pub impl_trait_bounds: RefCell<FxHashMap<DefId, Vec<clean::GenericBound>>>,
     pub send_trait: Option<DefId>,
     pub fake_def_ids: RefCell<FxHashMap<CrateNum, DefId>>,
     pub all_fake_def_ids: RefCell<FxHashSet<DefId>>,
index f85a70a6d401f24c5bcb09f4923426df1b74b1cd..0807db2997626fadc34b8a4de1432792a06cf4e6 100644 (file)
@@ -13,7 +13,6 @@
 pub use self::StructType::*;
 pub use self::TypeBound::*;
 
-use rustc_target::spec::abi;
 use syntax::ast;
 use syntax::ast::{Name, NodeId};
 use syntax::attr;
@@ -149,11 +148,9 @@ pub struct Function {
     pub vis: hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
-    pub unsafety: hir::Unsafety,
-    pub constness: hir::Constness,
+    pub header: hir::FnHeader,
     pub whence: Span,
     pub generics: hir::Generics,
-    pub abi: abi::Abi,
     pub body: hir::BodyId,
 }
 
@@ -201,7 +198,7 @@ pub struct Trait {
     pub name: Name,
     pub items: hir::HirVec<hir::TraitItem>,
     pub generics: hir::Generics,
-    pub bounds: hir::HirVec<hir::TyParamBound>,
+    pub bounds: hir::HirVec<hir::GenericBound>,
     pub attrs: hir::HirVec<ast::Attribute>,
     pub id: ast::NodeId,
     pub whence: Span,
index 40dcd6e891fe8cfba1161c4335c4fd7c33c2b580..2377354b85f6bf587e41d17a2cab2ea8db90afa4 100644 (file)
 /// with a space after it.
 #[derive(Copy, Clone)]
 pub struct ConstnessSpace(pub hir::Constness);
+/// Similarly to VisSpace, this structure is used to render a function asyncness
+/// with a space after it.
+#[derive(Copy, Clone)]
+pub struct AsyncSpace(pub hir::IsAsync);
 /// Similar to VisSpace, but used for mutability
 #[derive(Copy, Clone)]
 pub struct MutableSpace(pub clean::Mutability);
@@ -46,7 +50,7 @@
 #[derive(Copy, Clone)]
 pub struct RawMutableSpace(pub clean::Mutability);
 /// Wrapper struct for emitting type parameter bounds.
-pub struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]);
+pub struct GenericBounds<'a>(pub &'a [clean::GenericBound]);
 /// Wrapper struct for emitting a comma-separated list of items
 pub struct CommaSep<'a, T: 'a>(pub &'a [T]);
 pub struct AbiSpace(pub Abi);
@@ -104,9 +108,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl<'a> fmt::Display for TyParamBounds<'a> {
+impl<'a> fmt::Display for GenericBounds<'a> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let &TyParamBounds(bounds) = self;
+        let &GenericBounds(bounds) = self;
         for (i, bound) in bounds.iter().enumerate() {
             if i > 0 {
                 f.write_str(" + ")?;
@@ -119,20 +123,20 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 impl fmt::Display for clean::GenericParamDef {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            clean::GenericParamDef::Lifetime(ref lp) => write!(f, "{}", lp),
-            clean::GenericParamDef::Type(ref tp) => {
-                f.write_str(&tp.name)?;
+        match self.kind {
+            clean::GenericParamDefKind::Lifetime => write!(f, "{}", self.name),
+            clean::GenericParamDefKind::Type { ref bounds, ref default, .. } => {
+                f.write_str(&self.name)?;
 
-                if !tp.bounds.is_empty() {
+                if !bounds.is_empty() {
                     if f.alternate() {
-                        write!(f, ": {:#}", TyParamBounds(&tp.bounds))?;
+                        write!(f, ": {:#}", GenericBounds(bounds))?;
                     } else {
-                        write!(f, ":&nbsp;{}", TyParamBounds(&tp.bounds))?;
+                        write!(f, ":&nbsp;{}", GenericBounds(bounds))?;
                     }
                 }
 
-                if let Some(ref ty) = tp.default {
+                if let Some(ref ty) = default {
                     if f.alternate() {
                         write!(f, " = {:#}", ty)?;
                     } else {
@@ -190,9 +194,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 &clean::WherePredicate::BoundPredicate { ref ty, ref bounds } => {
                     let bounds = bounds;
                     if f.alternate() {
-                        clause.push_str(&format!("{:#}: {:#}", ty, TyParamBounds(bounds)));
+                        clause.push_str(&format!("{:#}: {:#}", ty, GenericBounds(bounds)));
                     } else {
-                        clause.push_str(&format!("{}: {}", ty, TyParamBounds(bounds)));
+                        clause.push_str(&format!("{}: {}", ty, GenericBounds(bounds)));
                     }
                 }
                 &clean::WherePredicate::RegionPredicate { ref lifetime,
@@ -267,13 +271,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl fmt::Display for clean::TyParamBound {
+impl fmt::Display for clean::GenericBound {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
-            clean::RegionBound(ref lt) => {
+            clean::GenericBound::Outlives(ref lt) => {
                 write!(f, "{}", *lt)
             }
-            clean::TraitBound(ref ty, modifier) => {
+            clean::GenericBound::TraitBound(ref ty, modifier) => {
                 let modifier_str = match modifier {
                     hir::TraitBoundModifier::None => "",
                     hir::TraitBoundModifier::Maybe => "?",
@@ -288,10 +292,10 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl fmt::Display for clean::PathParameters {
+impl fmt::Display for clean::GenericArgs {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
-            clean::PathParameters::AngleBracketed {
+            clean::GenericArgs::AngleBracketed {
                 ref lifetimes, ref types, ref bindings
             } => {
                 if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() {
@@ -337,7 +341,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                     }
                 }
             }
-            clean::PathParameters::Parenthesized { ref inputs, ref output } => {
+            clean::GenericArgs::Parenthesized { ref inputs, ref output } => {
                 f.write_str("(")?;
                 let mut comma = false;
                 for ty in inputs {
@@ -369,9 +373,9 @@ impl fmt::Display for clean::PathSegment {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.write_str(&self.name)?;
         if f.alternate() {
-            write!(f, "{:#}", self.params)
+            write!(f, "{:#}", self.args)
         } else {
-            write!(f, "{}", self.params)
+            write!(f, "{}", self.args)
         }
     }
 }
@@ -447,7 +451,7 @@ fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path,
         }
     }
     if w.alternate() {
-        write!(w, "{:#}{:#}", HRef::new(did, &last.name), last.params)?;
+        write!(w, "{:#}{:#}", HRef::new(did, &last.name), last.args)?;
     } else {
         let path = if use_absolute {
             match href(did) {
@@ -461,7 +465,7 @@ fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path,
         } else {
             format!("{}", HRef::new(did, &last.name))
         };
-        write!(w, "{}{}", path, last.params)?;
+        write!(w, "{}{}", path, last.args)?;
     }
     Ok(())
 }
@@ -512,7 +516,7 @@ fn primitive_link(f: &mut fmt::Formatter,
 
 /// Helper to render type parameters
 fn tybounds(w: &mut fmt::Formatter,
-            typarams: &Option<Vec<clean::TyParamBound>>) -> fmt::Result {
+            typarams: &Option<Vec<clean::GenericBound>>) -> fmt::Result {
     match *typarams {
         Some(ref params) => {
             for param in params {
@@ -667,7 +671,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt:
             }
         }
         clean::ImplTrait(ref bounds) => {
-            write!(f, "impl {}", TyParamBounds(bounds))
+            write!(f, "impl {}", GenericBounds(bounds))
         }
         clean::QPath { ref name, ref self_type, ref trait_ } => {
             let should_show_cast = match *trait_ {
@@ -757,7 +761,7 @@ fn fmt_impl(i: &clean::Impl,
                 clean::ResolvedPath { typarams: None, ref path, is_generic: false, .. } => {
                     let last = path.segments.last().unwrap();
                     fmt::Display::fmt(&last.name, f)?;
-                    fmt::Display::fmt(&last.params, f)?;
+                    fmt::Display::fmt(&last.args, f)?;
                 }
                 _ => unreachable!(),
             }
@@ -962,6 +966,15 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+impl fmt::Display for AsyncSpace {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self.0 {
+            hir::IsAsync::Async => write!(f, "async "),
+            hir::IsAsync::NotAsync => Ok(()),
+        }
+    }
+}
+
 impl fmt::Display for clean::Import {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
index 5c2ec2058ee9d703d0723b6cda9c8dc3a6592ee6..130451d07af8649bb188549cb6b2fd27c4d17c2c 100644 (file)
@@ -42,6 +42,7 @@
 use std::default::Default;
 use std::error;
 use std::fmt::{self, Display, Formatter, Write as FmtWrite};
+use std::ffi::OsStr;
 use std::fs::{self, File, OpenOptions};
 use std::io::prelude::*;
 use std::io::{self, BufWriter, BufReader};
 use rustc::hir;
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
 use rustc_data_structures::flock;
-use rustc_target::spec::abi;
 
 use clean::{self, AttributesExt, GetDefId, SelfTy, Mutability};
 use doctree;
 use fold::DocFolder;
 use html::escape::Escape;
-use html::format::{ConstnessSpace};
-use html::format::{TyParamBounds, WhereClause, href, AbiSpace};
+use html::format::{AsyncSpace, ConstnessSpace};
+use html::format::{GenericBounds, WhereClause, href, AbiSpace};
 use html::format::{VisSpace, Method, UnsafetySpace, MutableSpace};
 use html::format::fmt_impl_for_trait_page;
 use html::item_type::ItemType;
@@ -757,10 +757,12 @@ fn write_shared(cx: &Context,
     // Add all the static files. These may already exist, but we just
     // overwrite them anyway to make sure that they're fresh and up-to-date.
 
-    write(cx.dst.join(&format!("rustdoc{}.css", cx.shared.resource_suffix)),
-          include_bytes!("static/rustdoc.css"))?;
-    write(cx.dst.join(&format!("settings{}.css", cx.shared.resource_suffix)),
-          include_bytes!("static/settings.css"))?;
+    write_minify(cx.dst.join(&format!("rustdoc{}.css", cx.shared.resource_suffix)),
+                 include_str!("static/rustdoc.css"),
+                 enable_minification)?;
+    write_minify(cx.dst.join(&format!("settings{}.css", cx.shared.resource_suffix)),
+                 include_str!("static/settings.css"),
+                 enable_minification)?;
 
     // To avoid "light.css" to be overwritten, we'll first run over the received themes and only
     // then we'll run over the "official" styles.
@@ -782,11 +784,13 @@ fn write_shared(cx: &Context,
           include_bytes!("static/brush.svg"))?;
     write(cx.dst.join(&format!("wheel{}.svg", cx.shared.resource_suffix)),
           include_bytes!("static/wheel.svg"))?;
-    write(cx.dst.join(&format!("light{}.css", cx.shared.resource_suffix)),
-          include_bytes!("static/themes/light.css"))?;
+    write_minify(cx.dst.join(&format!("light{}.css", cx.shared.resource_suffix)),
+                 include_str!("static/themes/light.css"),
+                 enable_minification)?;
     themes.insert("light".to_owned());
-    write(cx.dst.join(&format!("dark{}.css", cx.shared.resource_suffix)),
-          include_bytes!("static/themes/dark.css"))?;
+    write_minify(cx.dst.join(&format!("dark{}.css", cx.shared.resource_suffix)),
+                 include_str!("static/themes/dark.css"),
+                 enable_minification)?;
     themes.insert("dark".to_owned());
 
     let mut themes: Vec<&String> = themes.iter().collect();
@@ -858,10 +862,19 @@ fn write_shared(cx: &Context,
 
     if let Some(ref css) = cx.shared.css_file_extension {
         let out = cx.dst.join(&format!("theme{}.css", cx.shared.resource_suffix));
-        try_err!(fs::copy(css, out), css);
+        if !enable_minification {
+            try_err!(fs::copy(css, out), css);
+        } else {
+            let mut f = try_err!(File::open(css), css);
+            let mut buffer = String::with_capacity(1000);
+
+            try_err!(f.read_to_string(&mut buffer), css);
+            write_minify(out, &buffer, enable_minification)?;
+        }
     }
-    write(cx.dst.join(&format!("normalize{}.css", cx.shared.resource_suffix)),
-          include_bytes!("static/normalize.css"))?;
+    write_minify(cx.dst.join(&format!("normalize{}.css", cx.shared.resource_suffix)),
+                 include_str!("static/normalize.css"),
+                 enable_minification)?;
     write(cx.dst.join("FiraSans-Regular.woff"),
           include_bytes!("static/FiraSans-Regular.woff"))?;
     write(cx.dst.join("FiraSans-Medium.woff"),
@@ -1052,7 +1065,12 @@ fn write(dst: PathBuf, contents: &[u8]) -> Result<(), Error> {
 
 fn write_minify(dst: PathBuf, contents: &str, enable_minification: bool) -> Result<(), Error> {
     if enable_minification {
-        write(dst, minifier::js::minify(contents).as_bytes())
+        if dst.extension() == Some(&OsStr::new("css")) {
+            let res = try_none!(minifier::css::minify(contents).ok(), &dst);
+            write(dst, res.as_bytes())
+        } else {
+            write(dst, minifier::js::minify(contents).as_bytes())
+        }
     } else {
         write(dst, contents.as_bytes())
     }
@@ -1453,11 +1471,11 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
 impl<'a> Cache {
     fn generics(&mut self, generics: &clean::Generics) {
         for param in &generics.params {
-            match *param {
-                clean::GenericParamDef::Type(ref typ) => {
-                    self.typarams.insert(typ.did, typ.name.clone());
+            match param.kind {
+                clean::GenericParamDefKind::Lifetime => {}
+                clean::GenericParamDefKind::Type { did, .. } => {
+                    self.typarams.insert(did, param.name.clone());
                 }
-                clean::GenericParamDef::Lifetime(_) => {}
             }
         }
     }
@@ -2405,7 +2423,7 @@ fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: usize, idx2: usize) -> Ordering
 
                 let unsafety_flag = match myitem.inner {
                     clean::FunctionItem(ref func) | clean::ForeignFunctionItem(ref func)
-                    if func.unsafety == hir::Unsafety::Unsafe => {
+                    if func.header.unsafety == hir::Unsafety::Unsafe => {
                         "<a title='unsafe function' href='#'><sup>⚠</sup></a>"
                     }
                     _ => "",
@@ -2575,21 +2593,24 @@ fn item_static(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
 
 fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
                  f: &clean::Function) -> fmt::Result {
-    let name_len = format!("{}{}{}{:#}fn {}{:#}",
+    let name_len = format!("{}{}{}{}{:#}fn {}{:#}",
                            VisSpace(&it.visibility),
-                           ConstnessSpace(f.constness),
-                           UnsafetySpace(f.unsafety),
-                           AbiSpace(f.abi),
+                           ConstnessSpace(f.header.constness),
+                           UnsafetySpace(f.header.unsafety),
+                           AsyncSpace(f.header.asyncness),
+                           AbiSpace(f.header.abi),
                            it.name.as_ref().unwrap(),
                            f.generics).len();
     write!(w, "{}<pre class='rust fn'>", render_spotlight_traits(it)?)?;
     render_attributes(w, it)?;
     write!(w,
-           "{vis}{constness}{unsafety}{abi}fn {name}{generics}{decl}{where_clause}</pre>",
+           "{vis}{constness}{unsafety}{asyncness}{abi}fn \
+           {name}{generics}{decl}{where_clause}</pre>",
            vis = VisSpace(&it.visibility),
-           constness = ConstnessSpace(f.constness),
-           unsafety = UnsafetySpace(f.unsafety),
-           abi = AbiSpace(f.abi),
+           constness = ConstnessSpace(f.header.constness),
+           unsafety = UnsafetySpace(f.header.unsafety),
+           asyncness = AsyncSpace(f.header.asyncness),
+           abi = AbiSpace(f.header.abi),
            name = it.name.as_ref().unwrap(),
            generics = f.generics,
            where_clause = WhereClause { gens: &f.generics, indent: 0, end_newline: true },
@@ -2960,14 +2981,14 @@ fn assoc_const(w: &mut fmt::Formatter,
 }
 
 fn assoc_type<W: fmt::Write>(w: &mut W, it: &clean::Item,
-                             bounds: &Vec<clean::TyParamBound>,
+                             bounds: &Vec<clean::GenericBound>,
                              default: Option<&clean::Type>,
                              link: AssocItemLink) -> fmt::Result {
     write!(w, "type <a href='{}' class=\"type\">{}</a>",
            naive_assoc_href(it, link),
            it.name.as_ref().unwrap())?;
     if !bounds.is_empty() {
-        write!(w, ": {}", TyParamBounds(bounds))?
+        write!(w, ": {}", GenericBounds(bounds))?
     }
     if let Some(default) = default {
         write!(w, " = {}", default)?;
@@ -2999,9 +3020,7 @@ fn render_assoc_item(w: &mut fmt::Formatter,
                      parent: ItemType) -> fmt::Result {
     fn method(w: &mut fmt::Formatter,
               meth: &clean::Item,
-              unsafety: hir::Unsafety,
-              constness: hir::Constness,
-              abi: abi::Abi,
+              header: hir::FnHeader,
               g: &clean::Generics,
               d: &clean::FnDecl,
               link: AssocItemLink,
@@ -3024,11 +3043,12 @@ fn method(w: &mut fmt::Formatter,
                 href(did).map(|p| format!("{}#{}.{}", p.0, ty, name)).unwrap_or(anchor)
             }
         };
-        let mut head_len = format!("{}{}{}{:#}fn {}{:#}",
+        let mut head_len = format!("{}{}{}{}{:#}fn {}{:#}",
                                    VisSpace(&meth.visibility),
-                                   ConstnessSpace(constness),
-                                   UnsafetySpace(unsafety),
-                                   AbiSpace(abi),
+                                   ConstnessSpace(header.constness),
+                                   UnsafetySpace(header.unsafety),
+                                   AsyncSpace(header.asyncness),
+                                   AbiSpace(header.abi),
                                    name,
                                    *g).len();
         let (indent, end_newline) = if parent == ItemType::Trait {
@@ -3038,12 +3058,13 @@ fn method(w: &mut fmt::Formatter,
             (0, true)
         };
         render_attributes(w, meth)?;
-        write!(w, "{}{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
+        write!(w, "{}{}{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
                    {generics}{decl}{where_clause}",
                VisSpace(&meth.visibility),
-               ConstnessSpace(constness),
-               UnsafetySpace(unsafety),
-               AbiSpace(abi),
+               ConstnessSpace(header.constness),
+               UnsafetySpace(header.unsafety),
+               AsyncSpace(header.asyncness),
+               AbiSpace(header.abi),
                href = href,
                name = name,
                generics = *g,
@@ -3061,12 +3082,10 @@ fn method(w: &mut fmt::Formatter,
     match item.inner {
         clean::StrippedItem(..) => Ok(()),
         clean::TyMethodItem(ref m) => {
-            method(w, item, m.unsafety, hir::Constness::NotConst,
-                   m.abi, &m.generics, &m.decl, link, parent)
+            method(w, item, m.header, &m.generics, &m.decl, link, parent)
         }
         clean::MethodItem(ref m) => {
-            method(w, item, m.unsafety, m.constness,
-                   m.abi, &m.generics, &m.decl, link, parent)
+            method(w, item, m.header, &m.generics, &m.decl, link, parent)
         }
         clean::AssociatedConstItem(ref ty, ref default) => {
             assoc_const(w, item, ty, default.as_ref(), link)
index d684db152df0129aff972b2570da44eb8a0555fd..575a7ea27921f0e9581e4276f30ce6ec2311a1ae 100644 (file)
@@ -407,31 +407,27 @@ h4 > code, h3 > code, .invisible > code {
 
 .content table:not(.table-display) {
        border-spacing: 0 5px;
-       border-collapse: separate;
 }
 .content td { vertical-align: top; }
 .content td:first-child { padding-right: 20px; }
 .content td p:first-child { margin-top: 0; }
 .content td h1, .content td h2 { margin-left: 0; font-size: 1.1em; }
+.content tr:first-child td { border-top: 0; }
 
 .docblock table {
-       border: 1px solid;
        margin: .5em 0;
-       border-collapse: collapse;
        width: 100%;
 }
 
 .docblock table td {
        padding: .5em;
-       border-top: 1px dashed;
-       border-bottom: 1px dashed;
+       border: 1px dashed;
 }
 
 .docblock table th {
        padding: .5em;
        text-align: left;
-       border-top: 1px solid;
-       border-bottom: 1px solid;
+       border: 1px solid;
 }
 
 .fields + table {
index 3a38a8c29d7884281ac4ce69244aa1d028a1ab84..566e2f1ed498c47fd8e7fbc1fc442b32b7e161b3 100644 (file)
@@ -18,6 +18,7 @@
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(fs_read_write)]
+#![feature(iterator_find_map)]
 #![feature(set_stdio)]
 #![feature(slice_sort_by_cached_key)]
 #![feature(test)]
index 10b1a2e1e0b67a0c413364ff8f4ea06e762f62bf..6bf1931e468dece633fd29456b204a28fe24cf35 100644 (file)
@@ -13,7 +13,6 @@
 
 use std::mem;
 
-use rustc_target::spec::abi;
 use syntax::ast;
 use syntax::attr;
 use syntax_pos::Span;
@@ -172,9 +171,7 @@ pub fn visit_enum_def(&mut self, it: &hir::Item,
 
     pub fn visit_fn(&mut self, item: &hir::Item,
                     name: ast::Name, fd: &hir::FnDecl,
-                    unsafety: &hir::Unsafety,
-                    constness: hir::Constness,
-                    abi: &abi::Abi,
+                    header: hir::FnHeader,
                     gen: &hir::Generics,
                     body: hir::BodyId) -> Function {
         debug!("Visiting fn");
@@ -188,9 +185,7 @@ pub fn visit_fn(&mut self, item: &hir::Item,
             name,
             whence: item.span,
             generics: gen.clone(),
-            unsafety: *unsafety,
-            constness,
-            abi: *abi,
+            header,
             body,
         }
     }
@@ -463,9 +458,8 @@ pub fn visit_item(&mut self, item: &hir::Item,
                 om.structs.push(self.visit_variant_data(item, name, sd, gen)),
             hir::ItemUnion(ref sd, ref gen) =>
                 om.unions.push(self.visit_union_data(item, name, sd, gen)),
-            hir::ItemFn(ref fd, ref unsafety, constness, ref abi, ref gen, body) =>
-                om.fns.push(self.visit_fn(item, name, &**fd, unsafety,
-                                          constness, abi, gen, body)),
+            hir::ItemFn(ref fd, header, ref gen, body) =>
+                om.fns.push(self.visit_fn(item, name, &**fd, header, gen, body)),
             hir::ItemTy(ref ty, ref gen) => {
                 let t = Typedef {
                     ty: ty.clone(),
diff --git a/src/libstd/future.rs b/src/libstd/future.rs
new file mode 100644 (file)
index 0000000..c1cc36f
--- /dev/null
@@ -0,0 +1,116 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Asynchronous values.
+
+use core::cell::Cell;
+use core::marker::Unpin;
+use core::mem::PinMut;
+use core::option::Option;
+use core::ptr::NonNull;
+use core::task::{self, Poll};
+use core::ops::{Drop, Generator, GeneratorState};
+
+#[doc(inline)]
+pub use core::future::*;
+
+/// Wrap a future in a generator.
+///
+/// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give
+/// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`).
+#[unstable(feature = "gen_future", issue = "50547")]
+pub fn from_generator<T: Generator<Yield = ()>>(x: T) -> impl Future<Output = T::Return> {
+    GenFuture(x)
+}
+
+/// A wrapper around generators used to implement `Future` for `async`/`await` code.
+#[unstable(feature = "gen_future", issue = "50547")]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
+struct GenFuture<T: Generator<Yield = ()>>(T);
+
+// We rely on the fact that async/await futures are immovable in order to create
+// self-referential borrows in the underlying generator.
+impl<T: Generator<Yield = ()>> !Unpin for GenFuture<T> {}
+
+#[unstable(feature = "gen_future", issue = "50547")]
+impl<T: Generator<Yield = ()>> Future for GenFuture<T> {
+    type Output = T::Return;
+    fn poll(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
+        set_task_cx(cx, || match unsafe { PinMut::get_mut_unchecked(self).0.resume() } {
+            GeneratorState::Yielded(()) => Poll::Pending,
+            GeneratorState::Complete(x) => Poll::Ready(x),
+        })
+    }
+}
+
+thread_local! {
+    static TLS_CX: Cell<Option<NonNull<task::Context<'static>>>> = Cell::new(None);
+}
+
+struct SetOnDrop(Option<NonNull<task::Context<'static>>>);
+
+impl Drop for SetOnDrop {
+    fn drop(&mut self) {
+        TLS_CX.with(|tls_cx| {
+            tls_cx.set(self.0.take());
+        });
+    }
+}
+
+#[unstable(feature = "gen_future", issue = "50547")]
+/// Sets the thread-local task context used by async/await futures.
+pub fn set_task_cx<F, R>(cx: &mut task::Context, f: F) -> R
+where
+    F: FnOnce() -> R
+{
+    let old_cx = TLS_CX.with(|tls_cx| {
+        tls_cx.replace(NonNull::new(
+            cx
+                as *mut task::Context
+                as *mut ()
+                as *mut task::Context<'static>
+        ))
+    });
+    let _reset_cx = SetOnDrop(old_cx);
+    f()
+}
+
+#[unstable(feature = "gen_future", issue = "50547")]
+/// Retrieves the thread-local task context used by async/await futures.
+///
+/// This function acquires exclusive access to the task context.
+///
+/// Panics if no task has been set or if the task context has already been
+/// retrived by a surrounding call to get_task_cx.
+pub fn get_task_cx<F, R>(f: F) -> R
+where
+    F: FnOnce(&mut task::Context) -> R
+{
+    let cx_ptr = TLS_CX.with(|tls_cx| {
+        // Clear the entry so that nested `with_get_cx` calls
+        // will fail or set their own value.
+        tls_cx.replace(None)
+    });
+    let _reset_cx = SetOnDrop(cx_ptr);
+
+    let mut cx_ptr = cx_ptr.expect(
+        "TLS task::Context not set. This is a rustc bug. \
+        Please file an issue on https://github.com/rust-lang/rust.");
+    unsafe { f(cx_ptr.as_mut()) }
+}
+
+#[unstable(feature = "gen_future", issue = "50547")]
+/// Polls a future in the current thread-local task context.
+pub fn poll_in_task_cx<F>(f: &mut PinMut<F>) -> Poll<F::Output>
+where
+    F: Future
+{
+    get_task_cx(|cx| f.reborrow().poll(cx))
+}
index a6061e96ae587d3cccc4d43a42a7e27727c38dfc..caad924ea5b5f0af581e0db5a1041bd99c811df5 100644 (file)
 #![feature(fn_traits)]
 #![feature(fnbox)]
 #![feature(futures_api)]
+#![feature(generator_trait)]
 #![feature(hashmap_internals)]
 #![feature(int_error_internals)]
 #![feature(integer_atomics)]
 #[stable(feature = "core_hint", since = "1.27.0")]
 pub use core::hint;
 
-#[unstable(feature = "futures_api",
-           reason = "futures in libcore are unstable",
-           issue = "50547")]
-pub mod task {
-    //! Types and Traits for working with asynchronous tasks.
-    #[doc(inline)]
-    pub use core::task::*;
-    #[doc(inline)]
-    pub use alloc_crate::task::*;
-}
-
-#[unstable(feature = "futures_api",
-           reason = "futures in libcore are unstable",
-           issue = "50547")]
-pub use core::future;
-
 pub mod f32;
 pub mod f64;
 
@@ -499,6 +484,22 @@ pub mod task {
 pub mod sync;
 pub mod time;
 
+#[unstable(feature = "futures_api",
+           reason = "futures in libcore are unstable",
+           issue = "50547")]
+pub mod task {
+    //! Types and Traits for working with asynchronous tasks.
+    #[doc(inline)]
+    pub use core::task::*;
+    #[doc(inline)]
+    pub use alloc_crate::task::*;
+}
+
+#[unstable(feature = "futures_api",
+           reason = "futures in libcore are unstable",
+           issue = "50547")]
+pub mod future;
+
 // Platform-abstraction modules
 #[macro_use]
 mod sys_common;
index 8da70f5717e71bef576648a60ad34baf9075e0f0..75f038407c12714d52729f1d29e77014282e04ba 100644 (file)
 /// The multi-argument form of this macro panics with a string and has the
 /// [`format!`] syntax for building a string.
 ///
+/// See also the macro [`compile_error!`], for raising errors during compilation.
+///
 /// [runwrap]: ../std/result/enum.Result.html#method.unwrap
 /// [`Option`]: ../std/option/enum.Option.html#method.unwrap
 /// [`Result`]: ../std/result/enum.Result.html
 /// [`format!`]: ../std/macro.format.html
+/// [`compile_error!`]: ../std/macro.compile_error.html
 /// [book]: ../book/second-edition/ch09-01-unrecoverable-errors-with-panic.html
 ///
 /// # Current implementation
@@ -213,6 +216,25 @@ macro_rules! eprintln {
     ($fmt:expr, $($arg:tt)*) => (eprint!(concat!($fmt, "\n"), $($arg)*));
 }
 
+#[macro_export]
+#[unstable(feature = "await_macro", issue = "50547")]
+#[allow_internal_unstable]
+#[allow_internal_unsafe]
+macro_rules! await {
+    ($e:expr) => { {
+        let mut pinned = $e;
+        let mut pinned = unsafe { $crate::mem::PinMut::new_unchecked(&mut pinned) };
+        loop {
+            match $crate::future::poll_in_task_cx(&mut pinned) {
+                // FIXME(cramertj) prior to stabilizing await, we have to ensure that this
+                // can't be used to create a generator on stable via `|| await!()`.
+                $crate::task::Poll::Pending => yield,
+                $crate::task::Poll::Ready(x) => break x,
+            }
+        }
+    } }
+}
+
 /// A macro to select an event from a number of receivers.
 ///
 /// This macro is used to wait for the first event to occur on a number of
@@ -286,13 +308,16 @@ pub mod builtin {
     /// Unconditionally causes compilation to fail with the given error message when encountered.
     ///
     /// This macro should be used when a crate uses a conditional compilation strategy to provide
-    /// better error messages for erroneous conditions.
+    /// better error messages for erroneous conditions. It's the compiler-level form of [`panic!`],
+    /// which emits an error at *runtime*, rather than during compilation.
     ///
     /// # Examples
     ///
     /// Two such examples are macros and `#[cfg]` environments.
     ///
-    /// Emit better compiler error if a macro is passed invalid values.
+    /// Emit better compiler error if a macro is passed invalid values. Without the final branch,
+    /// the compiler would still emit an error, but the error's message would not mention the two
+    /// valid values.
     ///
     /// ```compile_fail
     /// macro_rules! give_me_foo_or_bar {
@@ -313,6 +338,8 @@ pub mod builtin {
     /// #[cfg(not(any(feature = "foo", feature = "bar")))]
     /// compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate.")
     /// ```
+    ///
+    /// [`panic!`]: ../std/macro.panic.html
     #[stable(feature = "compile_error_macro", since = "1.20.0")]
     #[macro_export]
     macro_rules! compile_error {
index 4b5a063ea73aa2a5b823be0667a874022da31ef6..451420ae88ad8179f1ec1f37efaad1a458bf13fb 100644 (file)
 ///
 /// [`AssertUnwindSafe`]: ./struct.AssertUnwindSafe.html
 #[stable(feature = "catch_unwind", since = "1.9.0")]
-#[rustc_on_unimplemented = "the type {Self} may not be safely transferred \
-                            across an unwind boundary"]
+#[rustc_on_unimplemented(
+    message="the type `{Self}` may not be safely transferred across an unwind boundary",
+    label="`{Self}` may not be safely transferred across an unwind boundary",
+)]
 pub auto trait UnwindSafe {}
 
 /// A marker trait representing types where a shared reference is considered
 /// [`UnsafeCell`]: ../cell/struct.UnsafeCell.html
 /// [`UnwindSafe`]: ./trait.UnwindSafe.html
 #[stable(feature = "catch_unwind", since = "1.9.0")]
-#[rustc_on_unimplemented = "the type {Self} may contain interior mutability \
-                            and a reference may not be safely transferrable \
-                            across a catch_unwind boundary"]
+#[rustc_on_unimplemented(
+    message="the type `{Self}` may contain interior mutability and a reference may not be safely \
+             transferrable across a catch_unwind boundary",
+    label="`{Self}` may contain interior mutability and a reference may not be safely \
+           transferrable across a catch_unwind boundary",
+)]
 pub auto trait RefUnwindSafe {}
 
 /// A simple wrapper around a type to assert that it is unwind safe.
@@ -322,14 +327,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 impl<'a, F: Future> Future for AssertUnwindSafe<F> {
     type Output = F::Output;
 
-    fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
-        unsafe {
-            let pinned_field = PinMut::new_unchecked(
-                &mut PinMut::get_mut(self.reborrow()).0
-            );
-
-            pinned_field.poll(cx)
-        }
+    fn poll(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
+        let pinned_field = unsafe { PinMut::map_unchecked(self, |x| &mut x.0) };
+        pinned_field.poll(cx)
     }
 }
 
index 1231898ed7eba0051edc90b95fd0babf9ee7aece..c44db3b10722494e4e925987dff53a206bd378b8 100644 (file)
@@ -67,6 +67,7 @@
         // (missing things in `libc` which is empty) so just omit everything
         // with an empty module
         #[unstable(issue = "0", feature = "std_internals")]
+        #[allow(missing_docs)]
         pub mod unix_ext {}
     } else {
         // On other platforms like Windows document the bare bones of unix
@@ -80,11 +81,13 @@ pub mod unix_ext {}
 cfg_if! {
     if #[cfg(windows)] {
         // On windows we'll just be documenting what's already available
+        #[allow(missing_docs)]
         pub use self::ext as windows_ext;
     } else if #[cfg(any(target_os = "cloudabi", target_arch = "wasm32"))] {
         // On CloudABI and wasm right now the shim below doesn't compile, so
         // just omit it
         #[unstable(issue = "0", feature = "std_internals")]
+        #[allow(missing_docs)]
         pub mod windows_ext {}
     } else {
         // On all other platforms (aka linux/osx/etc) then pull in a "minimal"
index 774340388e1db9b7fe38a3646aec42e5c8d13813..662a76d6725a68d7bb3493c7229330d446e1dd80 100644 (file)
 
 #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "l4re"))]
 use libc::{stat64, fstat64, lstat64, off64_t, ftruncate64, lseek64, dirent64, readdir64_r, open64};
+#[cfg(any(target_os = "linux", target_os = "emscripten"))]
+use libc::fstatat64;
 #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "android"))]
-use libc::{fstatat, dirfd};
+use libc::dirfd;
 #[cfg(target_os = "android")]
-use libc::{stat as stat64, fstat as fstat64, lstat as lstat64, lseek64,
+use libc::{stat as stat64, fstat as fstat64, fstatat as fstatat64, lstat as lstat64, lseek64,
            dirent as dirent64, open as open64};
 #[cfg(not(any(target_os = "linux",
               target_os = "emscripten",
@@ -57,7 +59,10 @@ struct InnerReadDir {
 }
 
 #[derive(Clone)]
-pub struct ReadDir(Arc<InnerReadDir>);
+pub struct ReadDir {
+    inner: Arc<InnerReadDir>,
+    end_of_stream: bool,
+}
 
 struct Dir(*mut libc::DIR);
 
@@ -213,7 +218,7 @@ impl fmt::Debug for ReadDir {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         // This will only be called from std::fs::ReadDir, which will add a "ReadDir()" frame.
         // Thus the result will be e g 'ReadDir("/home")'
-        fmt::Debug::fmt(&*self.0.root, f)
+        fmt::Debug::fmt(&*self.inner.root, f)
     }
 }
 
@@ -229,7 +234,7 @@ fn next(&mut self) -> Option<io::Result<DirEntry>> {
                 // is safe to use in threaded applications and it is generally preferred
                 // over the readdir_r(3C) function.
                 super::os::set_errno(0);
-                let entry_ptr = libc::readdir(self.0.dirp.0);
+                let entry_ptr = libc::readdir(self.inner.dirp.0);
                 if entry_ptr.is_null() {
                     // NULL can mean either the end is reached or an error occurred.
                     // So we had to clear errno beforehand to check for an error now.
@@ -257,6 +262,10 @@ fn next(&mut self) -> Option<io::Result<DirEntry>> {
 
     #[cfg(not(any(target_os = "solaris", target_os = "fuchsia")))]
     fn next(&mut self) -> Option<io::Result<DirEntry>> {
+        if self.end_of_stream {
+            return None;
+        }
+
         unsafe {
             let mut ret = DirEntry {
                 entry: mem::zeroed(),
@@ -264,7 +273,14 @@ fn next(&mut self) -> Option<io::Result<DirEntry>> {
             };
             let mut entry_ptr = ptr::null_mut();
             loop {
-                if readdir64_r(self.0.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 {
+                if readdir64_r(self.inner.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 {
+                    if entry_ptr.is_null() {
+                        // We encountered an error (which will be returned in this iteration), but
+                        // we also reached the end of the directory stream. The `end_of_stream`
+                        // flag is enabled to make sure that we return `None` in the next iteration
+                        // (instead of looping forever)
+                        self.end_of_stream = true;
+                    }
                     return Some(Err(Error::last_os_error()))
                 }
                 if entry_ptr.is_null() {
@@ -287,7 +303,7 @@ fn drop(&mut self) {
 
 impl DirEntry {
     pub fn path(&self) -> PathBuf {
-        self.dir.0.root.join(OsStr::from_bytes(self.name_bytes()))
+        self.dir.inner.root.join(OsStr::from_bytes(self.name_bytes()))
     }
 
     pub fn file_name(&self) -> OsString {
@@ -296,13 +312,10 @@ pub fn file_name(&self) -> OsString {
 
     #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "android"))]
     pub fn metadata(&self) -> io::Result<FileAttr> {
-        let fd = cvt(unsafe {dirfd(self.dir.0.dirp.0)})?;
+        let fd = cvt(unsafe {dirfd(self.dir.inner.dirp.0)})?;
         let mut stat: stat64 = unsafe { mem::zeroed() };
         cvt(unsafe {
-            fstatat(fd,
-                    self.entry.d_name.as_ptr(),
-                    &mut stat as *mut _ as *mut _,
-                    libc::AT_SYMLINK_NOFOLLOW)
+            fstatat64(fd, self.entry.d_name.as_ptr(), &mut stat, libc::AT_SYMLINK_NOFOLLOW)
         })?;
         Ok(FileAttr { stat: stat })
     }
@@ -692,7 +705,10 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
             Err(Error::last_os_error())
         } else {
             let inner = InnerReadDir { dirp: Dir(ptr), root };
-            Ok(ReadDir(Arc::new(inner)))
+            Ok(ReadDir{
+                inner: Arc::new(inner),
+                end_of_stream: false,
+            })
         }
     }
 }
@@ -787,7 +803,7 @@ pub fn stat(p: &Path) -> io::Result<FileAttr> {
     let p = cstr(p)?;
     let mut stat: stat64 = unsafe { mem::zeroed() };
     cvt(unsafe {
-        stat64(p.as_ptr(), &mut stat as *mut _ as *mut _)
+        stat64(p.as_ptr(), &mut stat)
     })?;
     Ok(FileAttr { stat: stat })
 }
@@ -796,7 +812,7 @@ pub fn lstat(p: &Path) -> io::Result<FileAttr> {
     let p = cstr(p)?;
     let mut stat: stat64 = unsafe { mem::zeroed() };
     cvt(unsafe {
-        lstat64(p.as_ptr(), &mut stat as *mut _ as *mut _)
+        lstat64(p.as_ptr(), &mut stat)
     })?;
     Ok(FileAttr { stat: stat })
 }
index caa189457655230e1a47094fe73b054a308cdf2f..3f7f06714908428ee990b89fe15c483fe890d8ec 100644 (file)
@@ -183,15 +183,14 @@ pub fn fill_bytes(v: &mut [u8]) {
 mod imp {
     #[link(name = "zircon")]
     extern {
-        fn zx_cprng_draw(buffer: *mut u8, len: usize, actual: *mut usize) -> i32;
+        fn zx_cprng_draw_new(buffer: *mut u8, len: usize) -> i32;
     }
 
     fn getrandom(buf: &mut [u8]) -> Result<usize, i32> {
         unsafe {
-            let mut actual = 0;
-            let status = zx_cprng_draw(buf.as_mut_ptr(), buf.len(), &mut actual);
+            let status = zx_cprng_draw_new(buf.as_mut_ptr(), buf.len());
             if status == 0 {
-                Ok(actual)
+                Ok(buf.len())
             } else {
                 Err(status)
             }
index 76fa463a63134a494b49b05e191a487d2b5361c8..a57a9b95e5f776f3ad616aec9bc8de95cd7573a5 100644 (file)
 
 // The Rust abstract syntax tree.
 
-pub use self::TyParamBound::*;
 pub use self::UnsafeSource::*;
-pub use self::PathParameters::*;
+pub use self::GenericArgs::*;
 pub use symbol::{Ident, Symbol as Name};
 pub use util::ThinVec;
 pub use util::parser::ExprPrecedence;
 
 use syntax_pos::{Span, DUMMY_SP};
-use codemap::{respan, Spanned};
+use codemap::{dummy_spanned, respan, Spanned};
 use rustc_target::spec::abi::Abi;
 use ext::hygiene::{Mark, SyntaxContext};
 use print::pprust;
@@ -58,14 +57,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-/// A lifetime definition, e.g. `'a: 'b+'c+'d`
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct LifetimeDef {
-    pub attrs: ThinVec<Attribute>,
-    pub lifetime: Lifetime,
-    pub bounds: Vec<Lifetime>
-}
-
 /// A "Path" is essentially Rust's notion of a name.
 ///
 /// It's represented as a sequence of identifiers,
@@ -135,30 +126,30 @@ pub struct PathSegment {
     /// `Some` means that parameter list is supplied (`Path<X, Y>`)
     /// but it can be empty (`Path<>`).
     /// `P` is used as a size optimization for the common case with no parameters.
-    pub parameters: Option<P<PathParameters>>,
+    pub args: Option<P<GenericArgs>>,
 }
 
 impl PathSegment {
     pub fn from_ident(ident: Ident) -> Self {
-        PathSegment { ident, parameters: None }
+        PathSegment { ident, args: None }
     }
     pub fn crate_root(span: Span) -> Self {
         PathSegment::from_ident(Ident::new(keywords::CrateRoot.name(), span))
     }
 }
 
-/// Parameters of a path segment.
+/// Arguments of a path segment.
 ///
 /// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum PathParameters {
+pub enum GenericArgs {
     /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
-    AngleBracketed(AngleBracketedParameterData),
+    AngleBracketed(AngleBracketedArgs),
     /// The `(A,B)` and `C` in `Foo(A,B) -> C`
-    Parenthesized(ParenthesizedParameterData),
+    Parenthesized(ParenthesisedArgs),
 }
 
-impl PathParameters {
+impl GenericArgs {
     pub fn span(&self) -> Span {
         match *self {
             AngleBracketed(ref data) => data.span,
@@ -167,36 +158,40 @@ pub fn span(&self) -> Span {
     }
 }
 
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum GenericArg {
+    Lifetime(Lifetime),
+    Type(P<Ty>),
+}
+
 /// A path like `Foo<'a, T>`
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Default)]
-pub struct AngleBracketedParameterData {
+pub struct AngleBracketedArgs {
     /// Overall span
     pub span: Span,
-    /// The lifetime parameters for this path segment.
-    pub lifetimes: Vec<Lifetime>,
-    /// The type parameters for this path segment, if present.
-    pub types: Vec<P<Ty>>,
+    /// The arguments for this path segment.
+    pub args: Vec<GenericArg>,
     /// Bindings (equality constraints) on associated types, if present.
     ///
     /// E.g., `Foo<A=Bar>`.
     pub bindings: Vec<TypeBinding>,
 }
 
-impl Into<Option<P<PathParameters>>> for AngleBracketedParameterData {
-    fn into(self) -> Option<P<PathParameters>> {
-        Some(P(PathParameters::AngleBracketed(self)))
+impl Into<Option<P<GenericArgs>>> for AngleBracketedArgs {
+    fn into(self) -> Option<P<GenericArgs>> {
+        Some(P(GenericArgs::AngleBracketed(self)))
     }
 }
 
-impl Into<Option<P<PathParameters>>> for ParenthesizedParameterData {
-    fn into(self) -> Option<P<PathParameters>> {
-        Some(P(PathParameters::Parenthesized(self)))
+impl Into<Option<P<GenericArgs>>> for ParenthesisedArgs {
+    fn into(self) -> Option<P<GenericArgs>> {
+        Some(P(GenericArgs::Parenthesized(self)))
     }
 }
 
 /// A path like `Foo(A,B) -> C`
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct ParenthesizedParameterData {
+pub struct ParenthesisedArgs {
     /// Overall span
     pub span: Span,
 
@@ -273,64 +268,52 @@ fn index(self) -> usize {
 /// small, positive ids.
 pub const DUMMY_NODE_ID: NodeId = NodeId(!0);
 
+/// A modifier on a bound, currently this is only used for `?Sized`, where the
+/// modifier is `Maybe`. Negative bounds should also be handled here.
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum TraitBoundModifier {
+    None,
+    Maybe,
+}
+
 /// The AST represents all type param bounds as types.
 /// typeck::collect::compute_bounds matches these against
 /// the "special" built-in traits (see middle::lang_items) and
 /// detects Copy, Send and Sync.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum TyParamBound {
-    TraitTyParamBound(PolyTraitRef, TraitBoundModifier),
-    RegionTyParamBound(Lifetime)
+pub enum GenericBound {
+    Trait(PolyTraitRef, TraitBoundModifier),
+    Outlives(Lifetime)
 }
 
-impl TyParamBound {
+impl GenericBound {
     pub fn span(&self) -> Span {
         match self {
-            &TraitTyParamBound(ref t, ..) => t.span,
-            &RegionTyParamBound(ref l) => l.ident.span,
+            &GenericBound::Trait(ref t, ..) => t.span,
+            &GenericBound::Outlives(ref l) => l.ident.span,
         }
     }
 }
 
-/// A modifier on a bound, currently this is only used for `?Sized`, where the
-/// modifier is `Maybe`. Negative bounds should also be handled here.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum TraitBoundModifier {
-    None,
-    Maybe,
-}
-
-pub type TyParamBounds = Vec<TyParamBound>;
+pub type GenericBounds = Vec<GenericBound>;
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct TyParam {
-    pub attrs: ThinVec<Attribute>,
-    pub ident: Ident,
-    pub id: NodeId,
-    pub bounds: TyParamBounds,
-    pub default: Option<P<Ty>>,
+pub enum GenericParamKind {
+    /// A lifetime definition, e.g. `'a: 'b+'c+'d`.
+    Lifetime,
+    Type {
+        default: Option<P<Ty>>,
+    }
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum GenericParam {
-    Lifetime(LifetimeDef),
-    Type(TyParam),
-}
-
-impl GenericParam {
-    pub fn is_lifetime_param(&self) -> bool {
-        match *self {
-            GenericParam::Lifetime(_) => true,
-            _ => false,
-        }
-    }
+pub struct GenericParam {
+    pub id: NodeId,
+    pub ident: Ident,
+    pub attrs: ThinVec<Attribute>,
+    pub bounds: GenericBounds,
 
-    pub fn is_type_param(&self) -> bool {
-        match *self {
-            GenericParam::Type(_) => true,
-            _ => false,
-        }
-    }
+    pub kind: GenericParamKind,
 }
 
 /// Represents lifetime, type and const parameters attached to a declaration of
@@ -342,31 +325,6 @@ pub struct Generics {
     pub span: Span,
 }
 
-impl Generics {
-    pub fn is_lt_parameterized(&self) -> bool {
-        self.params.iter().any(|param| param.is_lifetime_param())
-    }
-
-    pub fn is_type_parameterized(&self) -> bool {
-        self.params.iter().any(|param| param.is_type_param())
-    }
-
-    pub fn is_parameterized(&self) -> bool {
-        !self.params.is_empty()
-    }
-
-    pub fn span_for_name(&self, name: &str) -> Option<Span> {
-        for param in &self.params {
-            if let GenericParam::Type(ref t) = *param {
-                if t.ident.name == name {
-                    return Some(t.ident.span);
-                }
-            }
-        }
-        None
-    }
-}
-
 impl Default for Generics {
     /// Creates an instance of `Generics`.
     fn default() ->  Generics {
@@ -422,7 +380,7 @@ pub struct WhereBoundPredicate {
     /// The type being bounded
     pub bounded_ty: P<Ty>,
     /// Trait and lifetime bounds (`Clone+Send+'static`)
-    pub bounds: TyParamBounds,
+    pub bounds: GenericBounds,
 }
 
 /// A lifetime predicate.
@@ -432,7 +390,7 @@ pub struct WhereBoundPredicate {
 pub struct WhereRegionPredicate {
     pub span: Span,
     pub lifetime: Lifetime,
-    pub bounds: Vec<Lifetime>,
+    pub bounds: GenericBounds,
 }
 
 /// An equality predicate (unsupported).
@@ -968,11 +926,11 @@ pub fn returns(&self) -> bool {
         }
     }
 
-    fn to_bound(&self) -> Option<TyParamBound> {
+    fn to_bound(&self) -> Option<GenericBound> {
         match &self.node {
             ExprKind::Path(None, path) =>
-                Some(TraitTyParamBound(PolyTraitRef::new(Vec::new(), path.clone(), self.span),
-                                       TraitBoundModifier::None)),
+                Some(GenericBound::Trait(PolyTraitRef::new(Vec::new(), path.clone(), self.span),
+                                         TraitBoundModifier::None)),
             _ => None,
         }
     }
@@ -1029,6 +987,7 @@ pub fn precedence(&self) -> ExprPrecedence {
             ExprKind::Closure(..) => ExprPrecedence::Closure,
             ExprKind::Block(..) => ExprPrecedence::Block,
             ExprKind::Catch(..) => ExprPrecedence::Catch,
+            ExprKind::Async(..) => ExprPrecedence::Async,
             ExprKind::Assign(..) => ExprPrecedence::Assign,
             ExprKind::AssignOp(..) => ExprPrecedence::AssignOp,
             ExprKind::Field(..) => ExprPrecedence::Field,
@@ -1136,9 +1095,18 @@ pub enum ExprKind {
     /// A closure (for example, `move |a, b, c| a + b + c`)
     ///
     /// The final span is the span of the argument block `|...|`
-    Closure(CaptureBy, Movability, P<FnDecl>, P<Expr>, Span),
+    Closure(CaptureBy, IsAsync, Movability, P<FnDecl>, P<Expr>, Span),
     /// A block (`'label: { ... }`)
     Block(P<Block>, Option<Label>),
+    /// An async block (`async move { ... }`)
+    ///
+    /// The `NodeId` is the `NodeId` for the closure that results from
+    /// desugaring an async block, just like the NodeId field in the
+    /// `IsAsync` enum. This is necessary in order to create a def for the
+    /// closure which can be used as a parent of any child defs. Defs
+    /// created during lowering cannot be made the parent of any other
+    /// preexisting defs.
+    Async(CaptureBy, NodeId, P<Block>),
     /// A catch block (`catch { ... }`)
     Catch(P<Block>),
 
@@ -1367,9 +1335,7 @@ pub struct MutTy {
 /// or in an implementation.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct MethodSig {
-    pub unsafety: Unsafety,
-    pub constness: Spanned<Constness>,
-    pub abi: Abi,
+    pub header: FnHeader,
     pub decl: P<FnDecl>,
 }
 
@@ -1393,7 +1359,7 @@ pub struct TraitItem {
 pub enum TraitItemKind {
     Const(P<Ty>, Option<P<Expr>>),
     Method(MethodSig, Option<P<Block>>),
-    Type(TyParamBounds, Option<P<Ty>>),
+    Type(GenericBounds, Option<P<Ty>>),
     Macro(Mac),
 }
 
@@ -1578,10 +1544,10 @@ pub enum TyKind {
     Path(Option<QSelf>, Path),
     /// A trait object type `Bound1 + Bound2 + Bound3`
     /// where `Bound` is a trait or a lifetime.
-    TraitObject(TyParamBounds, TraitObjectSyntax),
+    TraitObject(GenericBounds, TraitObjectSyntax),
     /// An `impl Bound1 + Bound2 + Bound3` type
     /// where `Bound` is a trait or a lifetime.
-    ImplTrait(TyParamBounds),
+    ImplTrait(GenericBounds),
     /// No-op; kept solely so that we can pretty-print faithfully
     Paren(P<Ty>),
     /// Unused for now
@@ -1750,6 +1716,22 @@ pub enum Unsafety {
     Normal,
 }
 
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum IsAsync {
+    Async(NodeId),
+    NotAsync,
+}
+
+impl IsAsync {
+    pub fn is_async(self) -> bool {
+        if let IsAsync::Async(_) = self {
+            true
+        } else {
+            false
+        }
+    }
+}
+
 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Constness {
     Const,
@@ -2051,6 +2033,29 @@ pub struct Item {
     pub tokens: Option<TokenStream>,
 }
 
+/// A function header
+///
+/// All the information between the visibility & the name of the function is
+/// included in this struct (e.g. `async unsafe fn` or `const extern "C" fn`)
+#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub struct FnHeader {
+    pub unsafety: Unsafety,
+    pub asyncness: IsAsync,
+    pub constness: Spanned<Constness>,
+    pub abi: Abi,
+}
+
+impl Default for FnHeader {
+    fn default() -> FnHeader {
+        FnHeader {
+            unsafety: Unsafety::Normal,
+            asyncness: IsAsync::NotAsync,
+            constness: dummy_spanned(Constness::NotConst),
+            abi: Abi::Rust,
+        }
+    }
+}
+
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum ItemKind {
     /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
@@ -2072,7 +2077,7 @@ pub enum ItemKind {
     /// A function declaration (`fn` or `pub fn`).
     ///
     /// E.g. `fn foo(bar: usize) -> usize { .. }`
-    Fn(P<FnDecl>, Unsafety, Spanned<Constness>, Abi, Generics, P<Block>),
+    Fn(P<FnDecl>, FnHeader, Generics, P<Block>),
     /// A module declaration (`mod` or `pub mod`).
     ///
     /// E.g. `mod foo;` or `mod foo { .. }`
@@ -2102,11 +2107,11 @@ pub enum ItemKind {
     /// A Trait declaration (`trait` or `pub trait`).
     ///
     /// E.g. `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`
-    Trait(IsAuto, Unsafety, Generics, TyParamBounds, Vec<TraitItem>),
+    Trait(IsAuto, Unsafety, Generics, GenericBounds, Vec<TraitItem>),
     /// Trait alias
     ///
     /// E.g. `trait Foo = Bar + Quux;`
-    TraitAlias(Generics, TyParamBounds),
+    TraitAlias(Generics, GenericBounds),
     /// An implementation.
     ///
     /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
index 2389ed799cfcc268301e70275aac9b3c190f029f..ded493fe3958c4f57a8e32db2e11a74646e08f4a 100644 (file)
@@ -1446,17 +1446,12 @@ fn map_attrs<F: FnOnce(Vec<ast::Attribute>) -> Vec<ast::Attribute>>(self, f: F)
 
 impl HasAttrs for GenericParam {
     fn attrs(&self) -> &[ast::Attribute] {
-        match self {
-            GenericParam::Lifetime(lifetime) => lifetime.attrs(),
-            GenericParam::Type(ty) => ty.attrs(),
-        }
+        &self.attrs
     }
 
-    fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
-        match self {
-            GenericParam::Lifetime(lifetime) => GenericParam::Lifetime(lifetime.map_attrs(f)),
-            GenericParam::Type(ty) => GenericParam::Type(ty.map_attrs(f)),
-        }
+    fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(mut self, f: F) -> Self {
+        self.attrs = self.attrs.map_attrs(f);
+        self
     }
 }
 
@@ -1479,5 +1474,5 @@ fn map_attrs<F>(mut self, f: F) -> Self
 
 derive_has_attrs! {
     Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::ImplItem, ast::TraitItem, ast::Arm,
-    ast::Field, ast::FieldPat, ast::Variant_, ast::LifetimeDef, ast::TyParam
+    ast::Field, ast::FieldPat, ast::Variant_
 }
index fe8ce75a4b8ea5483a8cc483e783d3f98901b2af..8e4b7660a1ccef89c20739d2134588f25e7852bb 100644 (file)
@@ -19,7 +19,7 @@
 
 
 pub use syntax_pos::*;
-pub use syntax_pos::hygiene::{ExpnFormat, ExpnInfo, NameAndSpan};
+pub use syntax_pos::hygiene::{ExpnFormat, ExpnInfo};
 pub use self::ExpnFormat::*;
 
 use rustc_data_structures::fx::FxHashMap;
index ab8317bfa027ea5b9b22fd04300985c8b92c47a2..8534969c623bc5c906c0c40625b6a7435b33d7c2 100644 (file)
@@ -397,4 +397,6 @@ fn main() {}
     E0630, // rustc_const_unstable attribute must be paired with stable/unstable attribute
     E0693, // incorrect `repr(align)` attribute format
     E0694, // an unknown tool name found in scoped attributes
+    E0703, // invalid ABI
+    E0704, // incorrect visibility restriction
 }
index 7c2eb540a30bb1da09530b74b93b002ea1016db0..16d786dd6cad2f76450618c0c917a80991d12e36 100644 (file)
@@ -16,7 +16,7 @@
 use syntax_pos::{Span, MultiSpan, DUMMY_SP};
 use edition::Edition;
 use errors::{DiagnosticBuilder, DiagnosticId};
-use ext::expand::{self, Expansion, Invocation};
+use ext::expand::{self, AstFragment, Invocation};
 use ext::hygiene::{self, Mark, SyntaxContext};
 use fold::{self, Folder};
 use parse::{self, parser, DirectoryOwnership};
@@ -597,7 +597,11 @@ pub enum SyntaxExtension {
     MultiModifier(Box<MultiItemModifier + sync::Sync + sync::Send>),
 
     /// A function-like procedural macro. TokenStream -> TokenStream.
-    ProcMacro(Box<ProcMacro + sync::Sync + sync::Send>, Edition),
+    ProcMacro(
+        /* expander: */ Box<ProcMacro + sync::Sync + sync::Send>,
+        /* allow_internal_unstable: */ bool,
+        /* edition: */ Edition,
+    ),
 
     /// An attribute-like procedural macro. TokenStream, TokenStream -> TokenStream.
     /// The first TokenSteam is the attribute, the second is the annotated item.
@@ -697,7 +701,8 @@ pub trait Resolver {
     fn eliminate_crate_var(&mut self, item: P<ast::Item>) -> P<ast::Item>;
     fn is_whitelisted_legacy_custom_derive(&self, name: Name) -> bool;
 
-    fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion, derives: &[Mark]);
+    fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
+                                            derives: &[Mark]);
     fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>);
 
     fn resolve_imports(&mut self);
@@ -726,7 +731,8 @@ fn get_module_scope(&mut self, _id: ast::NodeId) -> Mark { Mark::root() }
     fn eliminate_crate_var(&mut self, item: P<ast::Item>) -> P<ast::Item> { item }
     fn is_whitelisted_legacy_custom_derive(&self, _name: Name) -> bool { false }
 
-    fn visit_expansion(&mut self, _invoc: Mark, _expansion: &Expansion, _derives: &[Mark]) {}
+    fn visit_ast_fragment_with_placeholders(&mut self, _invoc: Mark, _fragment: &AstFragment,
+                                            _derives: &[Mark]) {}
     fn add_builtin(&mut self, _ident: ast::Ident, _ext: Lrc<SyntaxExtension>) {}
 
     fn resolve_imports(&mut self) {}
@@ -828,7 +834,7 @@ pub fn expansion_cause(&self) -> Option<Span> {
         let mut last_macro = None;
         loop {
             if ctxt.outer().expn_info().map_or(None, |info| {
-                if info.callee.name() == "include" {
+                if info.format.name() == "include" {
                     // Stop going up the backtrace once include! is encountered
                     return None;
                 }
index 4a6f06dcc17ba712e79543f7f3a419d508b59bf2..6135650766569ece2945ac5c94e56f9feb9da821 100644 (file)
@@ -30,10 +30,9 @@ pub trait AstBuilder {
     fn path_global(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path;
     fn path_all(&self, sp: Span,
                 global: bool,
-                idents: Vec<ast::Ident> ,
-                lifetimes: Vec<ast::Lifetime>,
-                types: Vec<P<ast::Ty>>,
-                bindings: Vec<ast::TypeBinding> )
+                idents: Vec<ast::Ident>,
+                args: Vec<ast::GenericArg>,
+                bindings: Vec<ast::TypeBinding>)
         -> ast::Path;
 
     fn qpath(&self, self_type: P<ast::Ty>,
@@ -43,8 +42,7 @@ fn qpath(&self, self_type: P<ast::Ty>,
     fn qpath_all(&self, self_type: P<ast::Ty>,
                 trait_path: ast::Path,
                 ident: ast::Ident,
-                lifetimes: Vec<ast::Lifetime>,
-                types: Vec<P<ast::Ty>>,
+                args: Vec<ast::GenericArg>,
                 bindings: Vec<ast::TypeBinding>)
                 -> (ast::QSelf, ast::Path);
 
@@ -70,19 +68,19 @@ fn typaram(&self,
                span: Span,
                id: ast::Ident,
                attrs: Vec<ast::Attribute>,
-               bounds: ast::TyParamBounds,
-               default: Option<P<ast::Ty>>) -> ast::TyParam;
+               bounds: ast::GenericBounds,
+               default: Option<P<ast::Ty>>) -> ast::GenericParam;
 
     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 trait_bound(&self, path: ast::Path) -> ast::GenericBound;
     fn lifetime(&self, span: Span, ident: ast::Ident) -> ast::Lifetime;
     fn lifetime_def(&self,
                     span: Span,
                     ident: ast::Ident,
                     attrs: Vec<ast::Attribute>,
-                    bounds: Vec<ast::Lifetime>)
-                    -> ast::LifetimeDef;
+                    bounds: ast::GenericBounds)
+                    -> ast::GenericParam;
 
     // statements
     fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt;
@@ -304,34 +302,33 @@ fn item_use_glob(&self, sp: Span,
 
 impl<'a> AstBuilder for ExtCtxt<'a> {
     fn path(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path {
-        self.path_all(span, false, strs, Vec::new(), Vec::new(), Vec::new())
+        self.path_all(span, false, strs, vec![], vec![])
     }
     fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path {
         self.path(span, vec![id])
     }
     fn path_global(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path {
-        self.path_all(span, true, strs, Vec::new(), Vec::new(), Vec::new())
+        self.path_all(span, true, strs, vec![], vec![])
     }
     fn path_all(&self,
                 span: Span,
                 global: bool,
                 mut idents: Vec<ast::Ident> ,
-                lifetimes: Vec<ast::Lifetime>,
-                types: Vec<P<ast::Ty>>,
+                args: Vec<ast::GenericArg>,
                 bindings: Vec<ast::TypeBinding> )
                 -> ast::Path {
         let last_ident = idents.pop().unwrap();
-        let mut segments: Vec<ast::PathSegment> = Vec::new();
+        let mut segments: Vec<ast::PathSegment> = vec![];
 
         segments.extend(idents.into_iter().map(|ident| {
             ast::PathSegment::from_ident(ident.with_span_pos(span))
         }));
-        let parameters = if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() {
-            ast::AngleBracketedParameterData { lifetimes, types, bindings, span }.into()
+        let args = if !args.is_empty() || !bindings.is_empty() {
+            ast::AngleBracketedArgs { args, bindings, span }.into()
         } else {
             None
         };
-        segments.push(ast::PathSegment { ident: last_ident.with_span_pos(span), parameters });
+        segments.push(ast::PathSegment { ident: last_ident.with_span_pos(span), args });
         let mut path = ast::Path { span, segments };
         if global {
             if let Some(seg) = path.make_root() {
@@ -349,7 +346,7 @@ fn qpath(&self,
              trait_path: ast::Path,
              ident: ast::Ident)
              -> (ast::QSelf, ast::Path) {
-        self.qpath_all(self_type, trait_path, ident, vec![], vec![], vec![])
+        self.qpath_all(self_type, trait_path, ident, vec![], vec![])
     }
 
     /// Constructs a qualified path.
@@ -359,17 +356,16 @@ fn qpath_all(&self,
                  self_type: P<ast::Ty>,
                  trait_path: ast::Path,
                  ident: ast::Ident,
-                 lifetimes: Vec<ast::Lifetime>,
-                 types: Vec<P<ast::Ty>>,
+                 args: Vec<ast::GenericArg>,
                  bindings: Vec<ast::TypeBinding>)
                  -> (ast::QSelf, ast::Path) {
         let mut path = trait_path;
-        let parameters = if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() {
-            ast::AngleBracketedParameterData { lifetimes, types, bindings, span: ident.span }.into()
+        let args = if !args.is_empty() || !bindings.is_empty() {
+            ast::AngleBracketedArgs { args, bindings, span: ident.span }.into()
         } else {
             None
         };
-        path.segments.push(ast::PathSegment { ident, parameters });
+        path.segments.push(ast::PathSegment { ident, args });
 
         (ast::QSelf {
             ty: self_type,
@@ -428,8 +424,7 @@ fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty> {
             self.path_all(DUMMY_SP,
                           true,
                           self.std_path(&["option", "Option"]),
-                          Vec::new(),
-                          vec![ ty ],
+                          vec![ast::GenericArg::Type(ty)],
                           Vec::new()))
     }
 
@@ -441,14 +436,16 @@ fn typaram(&self,
                span: Span,
                ident: ast::Ident,
                attrs: Vec<ast::Attribute>,
-               bounds: ast::TyParamBounds,
-               default: Option<P<ast::Ty>>) -> ast::TyParam {
-        ast::TyParam {
+               bounds: ast::GenericBounds,
+               default: Option<P<ast::Ty>>) -> ast::GenericParam {
+        ast::GenericParam {
             ident: ident.with_span_pos(span),
             id: ast::DUMMY_NODE_ID,
             attrs: attrs.into(),
             bounds,
-            default,
+            kind: ast::GenericParamKind::Type {
+                default,
+            }
         }
     }
 
@@ -467,8 +464,9 @@ fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef {
         }
     }
 
-    fn typarambound(&self, path: ast::Path) -> ast::TyParamBound {
-        ast::TraitTyParamBound(self.poly_trait_ref(path.span, path), ast::TraitBoundModifier::None)
+    fn trait_bound(&self, path: ast::Path) -> ast::GenericBound {
+        ast::GenericBound::Trait(self.poly_trait_ref(path.span, path),
+                                 ast::TraitBoundModifier::None)
     }
 
     fn lifetime(&self, span: Span, ident: ast::Ident) -> ast::Lifetime {
@@ -479,12 +477,15 @@ fn lifetime_def(&self,
                     span: Span,
                     ident: ast::Ident,
                     attrs: Vec<ast::Attribute>,
-                    bounds: Vec<ast::Lifetime>)
-                    -> ast::LifetimeDef {
-        ast::LifetimeDef {
+                    bounds: ast::GenericBounds)
+                    -> ast::GenericParam {
+        let lifetime = self.lifetime(span, ident);
+        ast::GenericParam {
+            ident: lifetime.ident,
+            id: lifetime.id,
             attrs: attrs.into(),
-            lifetime: self.lifetime(span, ident),
             bounds,
+            kind: ast::GenericParamKind::Lifetime,
         }
     }
 
@@ -914,6 +915,7 @@ fn lambda_fn_decl(&self,
                       fn_decl_span: Span) // span of the `|...|` part
                       -> P<ast::Expr> {
         self.expr(span, ast::ExprKind::Closure(ast::CaptureBy::Ref,
+                                               ast::IsAsync::NotAsync,
                                                ast::Movability::Movable,
                                                fn_decl,
                                                body,
@@ -934,6 +936,7 @@ fn lambda(&self,
         // the entire lambda body. Probably we should extend the API
         // here, but that's not entirely clear.
         self.expr(span, ast::ExprKind::Closure(ast::CaptureBy::Ref,
+                                               ast::IsAsync::NotAsync,
                                                ast::Movability::Movable,
                                                fn_decl,
                                                body,
@@ -1007,9 +1010,12 @@ fn item_fn_poly(&self,
                   name,
                   Vec::new(),
                   ast::ItemKind::Fn(self.fn_decl(inputs, ast::FunctionRetTy::Ty(output)),
-                              ast::Unsafety::Normal,
-                              dummy_spanned(ast::Constness::NotConst),
-                              Abi::Rust,
+                              ast::FnHeader {
+                                  unsafety: ast::Unsafety::Normal,
+                                  asyncness: ast::IsAsync::NotAsync,
+                                  constness: dummy_spanned(ast::Constness::NotConst),
+                                  abi: Abi::Rust,
+                              },
                               generics,
                               body))
     }
index 0b6a7e1c4f49dc2d6b13f27dab4d601226cf59ab..940fb6405f1b6065c170dfd7d7abc5ec9fdfd006 100644 (file)
@@ -10,7 +10,7 @@
 
 use attr::HasAttrs;
 use ast;
-use codemap::{hygiene, ExpnInfo, NameAndSpan, ExpnFormat};
+use codemap::{hygiene, ExpnInfo, ExpnFormat};
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use parse::parser::PathStyle;
@@ -60,13 +60,11 @@ pub fn add_derived_markers<T>(cx: &mut ExtCtxt, span: Span, traits: &[ast::Path]
 
     cx.current_expansion.mark.set_expn_info(ExpnInfo {
         call_site: span,
-        callee: NameAndSpan {
-            format: ExpnFormat::MacroAttribute(Symbol::intern(&pretty_name)),
-            span: None,
-            allow_internal_unstable: true,
-            allow_internal_unsafe: false,
-            edition: hygiene::default_edition(),
-        },
+        def_site: None,
+        format: ExpnFormat::MacroAttribute(Symbol::intern(&pretty_name)),
+        allow_internal_unstable: true,
+        allow_internal_unsafe: false,
+        edition: hygiene::default_edition(),
     });
 
     let span = span.with_ctxt(cx.backtrace());
index 29030783ca6b848d0c253c019fb30f126f76e4a7..69c99c63aafe3e55692d41ec91785063c00879c4 100644 (file)
@@ -11,7 +11,7 @@
 use ast::{self, Block, Ident, NodeId, PatKind, Path};
 use ast::{MacStmtStyle, StmtKind, ItemKind};
 use attr::{self, HasAttrs};
-use codemap::{ExpnInfo, NameAndSpan, MacroBang, MacroAttribute, dummy_spanned, respan};
+use codemap::{ExpnInfo, MacroBang, MacroAttribute, dummy_spanned, respan};
 use config::{is_test_or_bench, StripUnconfigured};
 use errors::{Applicability, FatalError};
 use ext::base::*;
 use std::rc::Rc;
 use std::path::PathBuf;
 
-macro_rules! expansions {
-    ($($kind:ident: $ty:ty [$($vec:ident, $ty_elt:ty)*], $kind_name:expr, .$make:ident,
-            $(.$fold:ident)*  $(lift .$fold_elt:ident)*,
-            $(.$visit:ident)*  $(lift .$visit_elt:ident)*;)*) => {
+macro_rules! ast_fragments {
+    (
+        $($Kind:ident($AstTy:ty) {
+            $kind_name:expr;
+            $(one fn $fold_ast:ident; fn $visit_ast:ident;)?
+            $(many fn $fold_ast_elt:ident; fn $visit_ast_elt:ident;)?
+            fn $make_ast:ident;
+        })*
+    ) => {
+        /// A fragment of AST that can be produced by a single macro expansion.
+        /// Can also serve as an input and intermediate result for macro expansion operations.
+        pub enum AstFragment {
+            OptExpr(Option<P<ast::Expr>>),
+            $($Kind($AstTy),)*
+        }
+
+        /// "Discriminant" of an AST fragment.
         #[derive(Copy, Clone, PartialEq, Eq)]
-        pub enum ExpansionKind { OptExpr, $( $kind, )*  }
-        pub enum Expansion { OptExpr(Option<P<ast::Expr>>), $( $kind($ty), )* }
+        pub enum AstFragmentKind {
+            OptExpr,
+            $($Kind,)*
+        }
 
-        impl ExpansionKind {
+        impl AstFragmentKind {
             pub fn name(self) -> &'static str {
                 match self {
-                    ExpansionKind::OptExpr => "expression",
-                    $( ExpansionKind::$kind => $kind_name, )*
+                    AstFragmentKind::OptExpr => "expression",
+                    $(AstFragmentKind::$Kind => $kind_name,)*
                 }
             }
 
-            fn make_from<'a>(self, result: Box<MacResult + 'a>) -> Option<Expansion> {
+            fn make_from<'a>(self, result: Box<MacResult + 'a>) -> Option<AstFragment> {
                 match self {
-                    ExpansionKind::OptExpr => result.make_expr().map(Some).map(Expansion::OptExpr),
-                    $( ExpansionKind::$kind => result.$make().map(Expansion::$kind), )*
+                    AstFragmentKind::OptExpr =>
+                        result.make_expr().map(Some).map(AstFragment::OptExpr),
+                    $(AstFragmentKind::$Kind => result.$make_ast().map(AstFragment::$Kind),)*
                 }
             }
         }
 
-        impl Expansion {
+        impl AstFragment {
             pub fn make_opt_expr(self) -> Option<P<ast::Expr>> {
                 match self {
-                    Expansion::OptExpr(expr) => expr,
-                    _ => panic!("Expansion::make_* called on the wrong kind of expansion"),
+                    AstFragment::OptExpr(expr) => expr,
+                    _ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
                 }
             }
-            $( pub fn $make(self) -> $ty {
+
+            $(pub fn $make_ast(self) -> $AstTy {
                 match self {
-                    Expansion::$kind(ast) => ast,
-                    _ => panic!("Expansion::make_* called on the wrong kind of expansion"),
+                    AstFragment::$Kind(ast) => ast,
+                    _ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
                 }
-            } )*
+            })*
 
             pub fn fold_with<F: Folder>(self, folder: &mut F) -> Self {
-                use self::Expansion::*;
                 match self {
-                    OptExpr(expr) => OptExpr(expr.and_then(|expr| folder.fold_opt_expr(expr))),
-                    $($( $kind(ast) => $kind(folder.$fold(ast)), )*)*
-                    $($( $kind(ast) => {
-                        $kind(ast.into_iter().flat_map(|ast| folder.$fold_elt(ast)).collect())
-                    }, )*)*
+                    AstFragment::OptExpr(expr) =>
+                        AstFragment::OptExpr(expr.and_then(|expr| folder.fold_opt_expr(expr))),
+                    $($(AstFragment::$Kind(ast) =>
+                        AstFragment::$Kind(folder.$fold_ast(ast)),)?)*
+                    $($(AstFragment::$Kind(ast) =>
+                        AstFragment::$Kind(ast.into_iter()
+                                              .flat_map(|ast| folder.$fold_ast_elt(ast))
+                                              .collect()),)?)*
                 }
             }
 
             pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) {
                 match *self {
-                    Expansion::OptExpr(Some(ref expr)) => visitor.visit_expr(expr),
-                    Expansion::OptExpr(None) => {}
-                    $($( Expansion::$kind(ref ast) => visitor.$visit(ast), )*)*
-                    $($( Expansion::$kind(ref ast) => for ast in &ast[..] {
-                        visitor.$visit_elt(ast);
-                    }, )*)*
+                    AstFragment::OptExpr(Some(ref expr)) => visitor.visit_expr(expr),
+                    AstFragment::OptExpr(None) => {}
+                    $($(AstFragment::$Kind(ref ast) => visitor.$visit_ast(ast),)?)*
+                    $($(AstFragment::$Kind(ref ast) => for ast_elt in &ast[..] {
+                        visitor.$visit_ast_elt(ast_elt);
+                    })?)*
                 }
             }
         }
 
         impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
             fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
-                self.expand(Expansion::OptExpr(Some(expr))).make_opt_expr()
+                self.expand_fragment(AstFragment::OptExpr(Some(expr))).make_opt_expr()
             }
-            $($(fn $fold(&mut self, node: $ty) -> $ty {
-                self.expand(Expansion::$kind(node)).$make()
-            })*)*
-            $($(fn $fold_elt(&mut self, node: $ty_elt) -> $ty {
-                self.expand(Expansion::$kind(SmallVector::one(node))).$make()
-            })*)*
+            $($(fn $fold_ast(&mut self, ast: $AstTy) -> $AstTy {
+                self.expand_fragment(AstFragment::$Kind(ast)).$make_ast()
+            })?)*
+            $($(fn $fold_ast_elt(&mut self, ast_elt: <$AstTy as IntoIterator>::Item) -> $AstTy {
+                self.expand_fragment(AstFragment::$Kind(SmallVector::one(ast_elt))).$make_ast()
+            })?)*
         }
 
         impl<'a> MacResult for ::ext::tt::macro_rules::ParserAnyMacro<'a> {
-            $(fn $make(self: Box<::ext::tt::macro_rules::ParserAnyMacro<'a>>) -> Option<$ty> {
-                Some(self.make(ExpansionKind::$kind).$make())
+            $(fn $make_ast(self: Box<::ext::tt::macro_rules::ParserAnyMacro<'a>>)
+                           -> Option<$AstTy> {
+                Some(self.make(AstFragmentKind::$Kind).$make_ast())
             })*
         }
     }
 }
 
-expansions! {
-    Expr: P<ast::Expr> [], "expression", .make_expr, .fold_expr, .visit_expr;
-    Pat: P<ast::Pat>   [], "pattern",    .make_pat,  .fold_pat,  .visit_pat;
-    Ty: P<ast::Ty>     [], "type",       .make_ty,   .fold_ty,   .visit_ty;
-    Stmts: SmallVector<ast::Stmt> [SmallVector, ast::Stmt],
-        "statement",  .make_stmts,       lift .fold_stmt, lift .visit_stmt;
-    Items: SmallVector<P<ast::Item>> [SmallVector, P<ast::Item>],
-        "item",       .make_items,       lift .fold_item, lift .visit_item;
-    TraitItems: SmallVector<ast::TraitItem> [SmallVector, ast::TraitItem],
-        "trait item", .make_trait_items, lift .fold_trait_item, lift .visit_trait_item;
-    ImplItems: SmallVector<ast::ImplItem> [SmallVector, ast::ImplItem],
-        "impl item",  .make_impl_items,  lift .fold_impl_item,  lift .visit_impl_item;
-    ForeignItems: SmallVector<ast::ForeignItem> [SmallVector, ast::ForeignItem],
-        "foreign item", .make_foreign_items, lift .fold_foreign_item, lift .visit_foreign_item;
+ast_fragments! {
+    Expr(P<ast::Expr>) { "expression"; one fn fold_expr; fn visit_expr; fn make_expr; }
+    Pat(P<ast::Pat>) { "pattern"; one fn fold_pat; fn visit_pat; fn make_pat; }
+    Ty(P<ast::Ty>) { "type"; one fn fold_ty; fn visit_ty; fn make_ty; }
+    Stmts(SmallVector<ast::Stmt>) { "statement"; many fn fold_stmt; fn visit_stmt; fn make_stmts; }
+    Items(SmallVector<P<ast::Item>>) { "item"; many fn fold_item; fn visit_item; fn make_items; }
+    TraitItems(SmallVector<ast::TraitItem>) {
+        "trait item"; many fn fold_trait_item; fn visit_trait_item; fn make_trait_items;
+    }
+    ImplItems(SmallVector<ast::ImplItem>) {
+        "impl item"; many fn fold_impl_item; fn visit_impl_item; fn make_impl_items;
+    }
+    ForeignItems(SmallVector<ast::ForeignItem>) {
+        "foreign item"; many fn fold_foreign_item; fn visit_foreign_item; fn make_foreign_items;
+    }
 }
 
-impl ExpansionKind {
-    fn dummy(self, span: Span) -> Option<Expansion> {
+impl AstFragmentKind {
+    fn dummy(self, span: Span) -> Option<AstFragment> {
         self.make_from(DummyResult::any(span))
     }
 
-    fn expect_from_annotatables<I: IntoIterator<Item = Annotatable>>(self, items: I) -> Expansion {
+    fn expect_from_annotatables<I: IntoIterator<Item = Annotatable>>(self, items: I)
+                                                                     -> AstFragment {
         let mut items = items.into_iter();
         match self {
-            ExpansionKind::Items =>
-                Expansion::Items(items.map(Annotatable::expect_item).collect()),
-            ExpansionKind::ImplItems =>
-                Expansion::ImplItems(items.map(Annotatable::expect_impl_item).collect()),
-            ExpansionKind::TraitItems =>
-                Expansion::TraitItems(items.map(Annotatable::expect_trait_item).collect()),
-            ExpansionKind::ForeignItems =>
-                Expansion::ForeignItems(items.map(Annotatable::expect_foreign_item).collect()),
-            ExpansionKind::Stmts => Expansion::Stmts(items.map(Annotatable::expect_stmt).collect()),
-            ExpansionKind::Expr => Expansion::Expr(
+            AstFragmentKind::Items =>
+                AstFragment::Items(items.map(Annotatable::expect_item).collect()),
+            AstFragmentKind::ImplItems =>
+                AstFragment::ImplItems(items.map(Annotatable::expect_impl_item).collect()),
+            AstFragmentKind::TraitItems =>
+                AstFragment::TraitItems(items.map(Annotatable::expect_trait_item).collect()),
+            AstFragmentKind::ForeignItems =>
+                AstFragment::ForeignItems(items.map(Annotatable::expect_foreign_item).collect()),
+            AstFragmentKind::Stmts =>
+                AstFragment::Stmts(items.map(Annotatable::expect_stmt).collect()),
+            AstFragmentKind::Expr => AstFragment::Expr(
                 items.next().expect("expected exactly one expression").expect_expr()
             ),
-            ExpansionKind::OptExpr =>
-                Expansion::OptExpr(items.next().map(Annotatable::expect_expr)),
-            ExpansionKind::Pat | ExpansionKind::Ty =>
+            AstFragmentKind::OptExpr =>
+                AstFragment::OptExpr(items.next().map(Annotatable::expect_expr)),
+            AstFragmentKind::Pat | AstFragmentKind::Ty =>
                 panic!("patterns and types aren't annotatable"),
         }
     }
@@ -187,7 +210,7 @@ fn macro_bang_format(path: &ast::Path) -> ExpnFormat {
 
 pub struct Invocation {
     pub kind: InvocationKind,
-    expansion_kind: ExpansionKind,
+    fragment_kind: AstFragmentKind,
     pub expansion_data: ExpansionData,
 }
 
@@ -244,7 +267,7 @@ pub fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
 
         let orig_mod_span = krate.module.inner;
 
-        let krate_item = Expansion::Items(SmallVector::one(P(ast::Item {
+        let krate_item = AstFragment::Items(SmallVector::one(P(ast::Item {
             attrs: krate.attrs,
             span: krate.span,
             node: ast::ItemKind::Mod(krate.module),
@@ -254,7 +277,7 @@ pub fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
             tokens: None,
         })));
 
-        match self.expand(krate_item).make_items().pop().map(P::into_inner) {
+        match self.expand_fragment(krate_item).make_items().pop().map(P::into_inner) {
             Some(ast::Item { attrs, node: ast::ItemKind::Mod(module), .. }) => {
                 krate.attrs = attrs;
                 krate.module = module;
@@ -273,16 +296,25 @@ pub fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
         krate
     }
 
-    // Fully expand all the invocations in `expansion`.
-    fn expand(&mut self, expansion: Expansion) -> Expansion {
+    // Fully expand all macro invocations in this AST fragment.
+    fn expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragment {
         let orig_expansion_data = self.cx.current_expansion.clone();
         self.cx.current_expansion.depth = 0;
 
-        let (expansion, mut invocations) = self.collect_invocations(expansion, &[]);
+        // Collect all macro invocations and replace them with placeholders.
+        let (fragment_with_placeholders, mut invocations)
+            = self.collect_invocations(input_fragment, &[]);
+
+        // Optimization: if we resolve all imports now,
+        // we'll be able to immediately resolve most of imported macros.
         self.resolve_imports();
-        invocations.reverse();
 
-        let mut expansions = Vec::new();
+        // Resolve paths in all invocations and produce ouput expanded fragments for them, but
+        // do not insert them into our input AST fragment yet, only store in `expanded_fragments`.
+        // The output fragments also go through expansion recursively until no invocations are left.
+        // Unresolved macros produce dummy outputs as a recovery measure.
+        invocations.reverse();
+        let mut expanded_fragments = Vec::new();
         let mut derives = HashMap::new();
         let mut undetermined_invocations = Vec::new();
         let (mut progress, mut force) = (false, !self.monotonic);
@@ -314,11 +346,11 @@ fn expand(&mut self, expansion: Expansion) -> Expansion {
 
             self.cx.current_expansion.mark = scope;
             // FIXME(jseyfried): Refactor out the following logic
-            let (expansion, new_invocations) = if let Some(ext) = ext {
+            let (expanded_fragment, new_invocations) = if let Some(ext) = ext {
                 if let Some(ext) = ext {
-                    let dummy = invoc.expansion_kind.dummy(invoc.span()).unwrap();
-                    let expansion = self.expand_invoc(invoc, &*ext).unwrap_or(dummy);
-                    self.collect_invocations(expansion, &[])
+                    let dummy = invoc.fragment_kind.dummy(invoc.span()).unwrap();
+                    let fragment = self.expand_invoc(invoc, &*ext).unwrap_or(dummy);
+                    self.collect_invocations(fragment, &[])
                 } else if let InvocationKind::Attr { attr: None, traits, item } = invoc.kind {
                     if !item.derive_allowed() {
                         let attr = attr::find_by_name(item.attrs(), "derive")
@@ -359,27 +391,27 @@ fn expand(&mut self, expansion: Expansion) -> Expansion {
                         };
                         invocations.push(Invocation {
                             kind: InvocationKind::Derive { path: path.clone(), item: item },
-                            expansion_kind: invoc.expansion_kind,
+                            fragment_kind: invoc.fragment_kind,
                             expansion_data: ExpansionData {
                                 mark,
                                 ..invoc.expansion_data.clone()
                             },
                         });
                     }
-                    let expansion = invoc.expansion_kind
+                    let fragment = invoc.fragment_kind
                         .expect_from_annotatables(::std::iter::once(item_with_markers));
-                    self.collect_invocations(expansion, derives)
+                    self.collect_invocations(fragment, derives)
                 } else {
                     unreachable!()
                 }
             } else {
-                self.collect_invocations(invoc.expansion_kind.dummy(invoc.span()).unwrap(), &[])
+                self.collect_invocations(invoc.fragment_kind.dummy(invoc.span()).unwrap(), &[])
             };
 
-            if expansions.len() < depth {
-                expansions.push(Vec::new());
+            if expanded_fragments.len() < depth {
+                expanded_fragments.push(Vec::new());
             }
-            expansions[depth - 1].push((mark, expansion));
+            expanded_fragments[depth - 1].push((mark, expanded_fragment));
             if !self.cx.ecfg.single_step {
                 invocations.extend(new_invocations.into_iter().rev());
             }
@@ -387,15 +419,16 @@ fn expand(&mut self, expansion: Expansion) -> Expansion {
 
         self.cx.current_expansion = orig_expansion_data;
 
+        // Finally incorporate all the expanded macros into the input AST fragment.
         let mut placeholder_expander = PlaceholderExpander::new(self.cx, self.monotonic);
-        while let Some(expansions) = expansions.pop() {
-            for (mark, expansion) in expansions.into_iter().rev() {
+        while let Some(expanded_fragments) = expanded_fragments.pop() {
+            for (mark, expanded_fragment) in expanded_fragments.into_iter().rev() {
                 let derives = derives.remove(&mark).unwrap_or_else(Vec::new);
-                placeholder_expander.add(NodeId::placeholder_from_mark(mark), expansion, derives);
+                placeholder_expander.add(NodeId::placeholder_from_mark(mark),
+                                         expanded_fragment, derives);
             }
         }
-
-        expansion.fold_with(&mut placeholder_expander)
+        fragment_with_placeholders.fold_with(&mut placeholder_expander)
     }
 
     fn resolve_imports(&mut self) {
@@ -406,9 +439,13 @@ fn resolve_imports(&mut self) {
         }
     }
 
-    fn collect_invocations(&mut self, expansion: Expansion, derives: &[Mark])
-                           -> (Expansion, Vec<Invocation>) {
-        let result = {
+    /// Collect all macro invocations reachable at this time in this AST fragment, and replace
+    /// them with "placeholders" - dummy macro invocations with specially crafted `NodeId`s.
+    /// Then call into resolver that builds a skeleton ("reduced graph") of the fragment and
+    /// prepares data for resolving paths of macro invocations.
+    fn collect_invocations(&mut self, fragment: AstFragment, derives: &[Mark])
+                           -> (AstFragment, Vec<Invocation>) {
+        let (fragment_with_placeholders, invocations) = {
             let mut collector = InvocationCollector {
                 cfg: StripUnconfigured {
                     should_test: self.cx.ecfg.should_test,
@@ -419,17 +456,18 @@ fn collect_invocations(&mut self, expansion: Expansion, derives: &[Mark])
                 invocations: Vec::new(),
                 monotonic: self.monotonic,
             };
-            (expansion.fold_with(&mut collector), collector.invocations)
+            (fragment.fold_with(&mut collector), collector.invocations)
         };
 
         if self.monotonic {
             let err_count = self.cx.parse_sess.span_diagnostic.err_count();
             let mark = self.cx.current_expansion.mark;
-            self.cx.resolver.visit_expansion(mark, &result.0, derives);
+            self.cx.resolver.visit_ast_fragment_with_placeholders(mark, &fragment_with_placeholders,
+                                                                  derives);
             self.cx.resolve_err_count += self.cx.parse_sess.span_diagnostic.err_count() - err_count;
         }
 
-        result
+        (fragment_with_placeholders, invocations)
     }
 
     fn fully_configure(&mut self, item: Annotatable) -> Annotatable {
@@ -464,7 +502,7 @@ fn fully_configure(&mut self, item: Annotatable) -> Annotatable {
         }
     }
 
-    fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) -> Option<Expansion> {
+    fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) -> Option<AstFragment> {
         let result = match invoc.kind {
             InvocationKind::Bang { .. } => self.expand_bang_invoc(invoc, ext)?,
             InvocationKind::Attr { .. } => self.expand_attr_invoc(invoc, ext)?,
@@ -476,7 +514,7 @@ fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) -> Option<E
             let suggested_limit = self.cx.ecfg.recursion_limit * 2;
             let mut err = self.cx.struct_span_err(info.call_site,
                 &format!("recursion limit reached while expanding the macro `{}`",
-                         info.callee.name()));
+                         info.format.name()));
             err.help(&format!(
                 "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
                 suggested_limit));
@@ -491,8 +529,7 @@ fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) -> Option<E
     fn expand_attr_invoc(&mut self,
                          invoc: Invocation,
                          ext: &SyntaxExtension)
-                         -> Option<Expansion> {
-        let Invocation { expansion_kind: kind, .. } = invoc;
+                         -> Option<AstFragment> {
         let (attr, item) = match invoc.kind {
             InvocationKind::Attr { attr, item, .. } => (attr?, item),
             _ => unreachable!(),
@@ -501,13 +538,11 @@ fn expand_attr_invoc(&mut self,
         attr::mark_used(&attr);
         invoc.expansion_data.mark.set_expn_info(ExpnInfo {
             call_site: attr.span,
-            callee: NameAndSpan {
-                format: MacroAttribute(Symbol::intern(&format!("{}", attr.path))),
-                span: None,
-                allow_internal_unstable: false,
-                allow_internal_unsafe: false,
-                edition: ext.edition(),
-            }
+            def_site: None,
+            format: MacroAttribute(Symbol::intern(&format!("{}", attr.path))),
+            allow_internal_unstable: false,
+            allow_internal_unsafe: false,
+            edition: ext.edition(),
         });
 
         match *ext {
@@ -515,7 +550,7 @@ fn expand_attr_invoc(&mut self,
                 let meta = attr.parse_meta(self.cx.parse_sess)
                                .map_err(|mut e| { e.emit(); }).ok()?;
                 let item = mac.expand(self.cx, attr.span, &meta, item);
-                Some(kind.expect_from_annotatables(item))
+                Some(invoc.fragment_kind.expect_from_annotatables(item))
             }
             MultiDecorator(ref mac) => {
                 let mut items = Vec::new();
@@ -523,7 +558,7 @@ fn expand_attr_invoc(&mut self,
                                .expect("derive meta should already have been parsed");
                 mac.expand(self.cx, attr.span, &meta, &item, &mut |item| items.push(item));
                 items.push(item);
-                Some(kind.expect_from_annotatables(items))
+                Some(invoc.fragment_kind.expect_from_annotatables(items))
             }
             AttrProcMacro(ref mac, ..) => {
                 self.gate_proc_macro_attr_item(attr.span, &item);
@@ -537,20 +572,21 @@ fn expand_attr_invoc(&mut self,
                 })).into();
                 let input = self.extract_proc_macro_attr_input(attr.tokens, attr.span);
                 let tok_result = mac.expand(self.cx, attr.span, input, item_tok);
-                let res = self.parse_expansion(tok_result, kind, &attr.path, attr.span);
+                let res = self.parse_ast_fragment(tok_result, invoc.fragment_kind,
+                                                  &attr.path, attr.span);
                 self.gate_proc_macro_expansion(attr.span, &res);
                 res
             }
             ProcMacroDerive(..) | BuiltinDerive(..) => {
                 self.cx.span_err(attr.span, &format!("`{}` is a derive mode", attr.path));
                 self.cx.trace_macros_diag();
-                kind.dummy(attr.span)
+                invoc.fragment_kind.dummy(attr.span)
             }
             _ => {
                 let msg = &format!("macro `{}` may not be used in attributes", attr.path);
                 self.cx.span_err(attr.span, msg);
                 self.cx.trace_macros_diag();
-                kind.dummy(attr.span)
+                invoc.fragment_kind.dummy(attr.span)
             }
         }
     }
@@ -598,16 +634,16 @@ fn gate_proc_macro_attr_item(&self, span: Span, item: &Annotatable) {
         );
     }
 
-    fn gate_proc_macro_expansion(&self, span: Span, expansion: &Option<Expansion>) {
+    fn gate_proc_macro_expansion(&self, span: Span, fragment: &Option<AstFragment>) {
         if self.cx.ecfg.proc_macro_gen() {
             return
         }
-        let expansion = match expansion {
-            Some(expansion) => expansion,
+        let fragment = match fragment {
+            Some(fragment) => fragment,
             None => return,
         };
 
-        expansion.visit_with(&mut DisallowModules {
+        fragment.visit_with(&mut DisallowModules {
             span,
             parse_sess: self.cx.parse_sess,
         });
@@ -642,12 +678,12 @@ fn visit_mac(&mut self, _mac: &'ast ast::Mac) {
         }
     }
 
-    /// Expand a macro invocation. Returns the result of expansion.
+    /// Expand a macro invocation. Returns the resulting expanded AST fragment.
     fn expand_bang_invoc(&mut self,
                          invoc: Invocation,
                          ext: &SyntaxExtension)
-                         -> Option<Expansion> {
-        let (mark, kind) = (invoc.expansion_data.mark, invoc.expansion_kind);
+                         -> Option<AstFragment> {
+        let (mark, kind) = (invoc.expansion_data.mark, invoc.fragment_kind);
         let (mac, ident, span) = match invoc.kind {
             InvocationKind::Bang { mac, ident, span } => (mac, ident, span),
             _ => unreachable!(),
@@ -689,13 +725,11 @@ fn expand_bang_invoc(&mut self,
             }
             mark.set_expn_info(ExpnInfo {
                 call_site: span,
-                callee: NameAndSpan {
-                    format: macro_bang_format(path),
-                    span: def_site_span,
-                    allow_internal_unstable,
-                    allow_internal_unsafe,
-                    edition,
-                },
+                def_site: def_site_span,
+                format: macro_bang_format(path),
+                allow_internal_unstable,
+                allow_internal_unsafe,
+                edition,
             });
             Ok(())
         };
@@ -739,13 +773,11 @@ fn expand_bang_invoc(&mut self,
                 } else {
                     invoc.expansion_data.mark.set_expn_info(ExpnInfo {
                         call_site: span,
-                        callee: NameAndSpan {
-                            format: macro_bang_format(path),
-                            span: tt_span,
-                            allow_internal_unstable,
-                            allow_internal_unsafe: false,
-                            edition: hygiene::default_edition(),
-                        }
+                        def_site: tt_span,
+                        format: macro_bang_format(path),
+                        allow_internal_unstable,
+                        allow_internal_unsafe: false,
+                        edition: hygiene::default_edition(),
                     });
 
                     let input: Vec<_> = mac.node.stream().into_trees().collect();
@@ -766,7 +798,7 @@ fn expand_bang_invoc(&mut self,
                 kind.dummy(span)
             }
 
-            ProcMacro(ref expandfun, edition) => {
+            ProcMacro(ref expandfun, allow_internal_unstable, edition) => {
                 if ident.name != keywords::Invalid.name() {
                     let msg =
                         format!("macro {}! expects no ident argument, given '{}'", path, ident);
@@ -777,20 +809,18 @@ fn expand_bang_invoc(&mut self,
                     self.gate_proc_macro_expansion_kind(span, kind);
                     invoc.expansion_data.mark.set_expn_info(ExpnInfo {
                         call_site: span,
-                        callee: NameAndSpan {
-                            format: macro_bang_format(path),
-                            // FIXME procedural macros do not have proper span info
-                            // yet, when they do, we should use it here.
-                            span: None,
-                            // FIXME probably want to follow macro_rules macros here.
-                            allow_internal_unstable: false,
-                            allow_internal_unsafe: false,
-                            edition,
-                        },
+                        // FIXME procedural macros do not have proper span info
+                        // yet, when they do, we should use it here.
+                        def_site: None,
+                        format: macro_bang_format(path),
+                        // FIXME probably want to follow macro_rules macros here.
+                        allow_internal_unstable,
+                        allow_internal_unsafe: false,
+                        edition,
                     });
 
                     let tok_result = expandfun.expand(self.cx, span, mac.node.stream());
-                    let result = self.parse_expansion(tok_result, kind, path, span);
+                    let result = self.parse_ast_fragment(tok_result, kind, path, span);
                     self.gate_proc_macro_expansion(span, &result);
                     result
                 }
@@ -808,17 +838,17 @@ fn expand_bang_invoc(&mut self,
         }
     }
 
-    fn gate_proc_macro_expansion_kind(&self, span: Span, kind: ExpansionKind) {
+    fn gate_proc_macro_expansion_kind(&self, span: Span, kind: AstFragmentKind) {
         let kind = match kind {
-            ExpansionKind::Expr => "expressions",
-            ExpansionKind::OptExpr => "expressions",
-            ExpansionKind::Pat => "patterns",
-            ExpansionKind::Ty => "types",
-            ExpansionKind::Stmts => "statements",
-            ExpansionKind::Items => return,
-            ExpansionKind::TraitItems => return,
-            ExpansionKind::ImplItems => return,
-            ExpansionKind::ForeignItems => return,
+            AstFragmentKind::Expr => "expressions",
+            AstFragmentKind::OptExpr => "expressions",
+            AstFragmentKind::Pat => "patterns",
+            AstFragmentKind::Ty => "types",
+            AstFragmentKind::Stmts => "statements",
+            AstFragmentKind::Items => return,
+            AstFragmentKind::TraitItems => return,
+            AstFragmentKind::ImplItems => return,
+            AstFragmentKind::ForeignItems => return,
         };
         if self.cx.ecfg.proc_macro_non_items() {
             return
@@ -832,12 +862,11 @@ fn gate_proc_macro_expansion_kind(&self, span: Span, kind: ExpansionKind) {
         );
     }
 
-    /// Expand a derive invocation. Returns the result of expansion.
+    /// Expand a derive invocation. Returns the resulting expanded AST fragment.
     fn expand_derive_invoc(&mut self,
                            invoc: Invocation,
                            ext: &SyntaxExtension)
-                           -> Option<Expansion> {
-        let Invocation { expansion_kind: kind, .. } = invoc;
+                           -> Option<AstFragment> {
         let (path, item) = match invoc.kind {
             InvocationKind::Derive { path, item } => (path, item),
             _ => unreachable!(),
@@ -857,13 +886,11 @@ fn expand_derive_invoc(&mut self,
 
         let mut expn_info = ExpnInfo {
             call_site: span,
-            callee: NameAndSpan {
-                format: MacroAttribute(pretty_name),
-                span: None,
-                allow_internal_unstable: false,
-                allow_internal_unsafe: false,
-                edition: ext.edition(),
-            }
+            def_site: None,
+            format: MacroAttribute(pretty_name),
+            allow_internal_unstable: false,
+            allow_internal_unsafe: false,
+            edition: ext.edition(),
         };
 
         match *ext {
@@ -876,36 +903,36 @@ fn expand_derive_invoc(&mut self,
                     node: ast::MetaItemKind::Word,
                 };
                 let items = ext.expand(self.cx, span, &dummy, item);
-                Some(kind.expect_from_annotatables(items))
+                Some(invoc.fragment_kind.expect_from_annotatables(items))
             }
             BuiltinDerive(func) => {
-                expn_info.callee.allow_internal_unstable = true;
+                expn_info.allow_internal_unstable = true;
                 invoc.expansion_data.mark.set_expn_info(expn_info);
                 let span = span.with_ctxt(self.cx.backtrace());
                 let mut items = Vec::new();
                 func(self.cx, span, &attr.meta()?, &item, &mut |a| items.push(a));
-                Some(kind.expect_from_annotatables(items))
+                Some(invoc.fragment_kind.expect_from_annotatables(items))
             }
             _ => {
                 let msg = &format!("macro `{}` may not be used for derive attributes", attr.path);
                 self.cx.span_err(span, msg);
                 self.cx.trace_macros_diag();
-                kind.dummy(span)
+                invoc.fragment_kind.dummy(span)
             }
         }
     }
 
-    fn parse_expansion(&mut self,
-                       toks: TokenStream,
-                       kind: ExpansionKind,
-                       path: &Path,
-                       span: Span)
-                       -> Option<Expansion> {
+    fn parse_ast_fragment(&mut self,
+                          toks: TokenStream,
+                          kind: AstFragmentKind,
+                          path: &Path,
+                          span: Span)
+                          -> Option<AstFragment> {
         let mut parser = self.cx.new_parser_from_tts(&toks.into_trees().collect::<Vec<_>>());
-        match parser.parse_expansion(kind, false) {
-            Ok(expansion) => {
+        match parser.parse_ast_fragment(kind, false) {
+            Ok(fragment) => {
                 parser.ensure_complete_parse(path, kind.name(), span);
-                Some(expansion)
+                Some(fragment)
             }
             Err(mut err) => {
                 err.set_span(span);
@@ -918,40 +945,40 @@ fn parse_expansion(&mut self,
 }
 
 impl<'a> Parser<'a> {
-    pub fn parse_expansion(&mut self, kind: ExpansionKind, macro_legacy_warnings: bool)
-                           -> PResult<'a, Expansion> {
+    pub fn parse_ast_fragment(&mut self, kind: AstFragmentKind, macro_legacy_warnings: bool)
+                              -> PResult<'a, AstFragment> {
         Ok(match kind {
-            ExpansionKind::Items => {
+            AstFragmentKind::Items => {
                 let mut items = SmallVector::new();
                 while let Some(item) = self.parse_item()? {
                     items.push(item);
                 }
-                Expansion::Items(items)
+                AstFragment::Items(items)
             }
-            ExpansionKind::TraitItems => {
+            AstFragmentKind::TraitItems => {
                 let mut items = SmallVector::new();
                 while self.token != token::Eof {
                     items.push(self.parse_trait_item(&mut false)?);
                 }
-                Expansion::TraitItems(items)
+                AstFragment::TraitItems(items)
             }
-            ExpansionKind::ImplItems => {
+            AstFragmentKind::ImplItems => {
                 let mut items = SmallVector::new();
                 while self.token != token::Eof {
                     items.push(self.parse_impl_item(&mut false)?);
                 }
-                Expansion::ImplItems(items)
+                AstFragment::ImplItems(items)
             }
-            ExpansionKind::ForeignItems => {
+            AstFragmentKind::ForeignItems => {
                 let mut items = SmallVector::new();
                 while self.token != token::Eof {
                     if let Some(item) = self.parse_foreign_item()? {
                         items.push(item);
                     }
                 }
-                Expansion::ForeignItems(items)
+                AstFragment::ForeignItems(items)
             }
-            ExpansionKind::Stmts => {
+            AstFragmentKind::Stmts => {
                 let mut stmts = SmallVector::new();
                 while self.token != token::Eof &&
                       // won't make progress on a `}`
@@ -960,18 +987,18 @@ pub fn parse_expansion(&mut self, kind: ExpansionKind, macro_legacy_warnings: bo
                         stmts.push(stmt);
                     }
                 }
-                Expansion::Stmts(stmts)
+                AstFragment::Stmts(stmts)
             }
-            ExpansionKind::Expr => Expansion::Expr(self.parse_expr()?),
-            ExpansionKind::OptExpr => {
+            AstFragmentKind::Expr => AstFragment::Expr(self.parse_expr()?),
+            AstFragmentKind::OptExpr => {
                 if self.token != token::Eof {
-                    Expansion::OptExpr(Some(self.parse_expr()?))
+                    AstFragment::OptExpr(Some(self.parse_expr()?))
                 } else {
-                    Expansion::OptExpr(None)
+                    AstFragment::OptExpr(None)
                 }
             },
-            ExpansionKind::Ty => Expansion::Ty(self.parse_ty()?),
-            ExpansionKind::Pat => Expansion::Pat(self.parse_pat()?),
+            AstFragmentKind::Ty => AstFragment::Ty(self.parse_ty()?),
+            AstFragmentKind::Pat => AstFragment::Pat(self.parse_pat()?),
         })
     }
 
@@ -998,21 +1025,21 @@ struct InvocationCollector<'a, 'b: 'a> {
 }
 
 impl<'a, 'b> InvocationCollector<'a, 'b> {
-    fn collect(&mut self, expansion_kind: ExpansionKind, kind: InvocationKind) -> Expansion {
+    fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> AstFragment {
         let mark = Mark::fresh(self.cx.current_expansion.mark);
         self.invocations.push(Invocation {
             kind,
-            expansion_kind,
+            fragment_kind,
             expansion_data: ExpansionData {
                 mark,
                 depth: self.cx.current_expansion.depth + 1,
                 ..self.cx.current_expansion.clone()
             },
         });
-        placeholder(expansion_kind, NodeId::placeholder_from_mark(mark))
+        placeholder(fragment_kind, NodeId::placeholder_from_mark(mark))
     }
 
-    fn collect_bang(&mut self, mac: ast::Mac, span: Span, kind: ExpansionKind) -> Expansion {
+    fn collect_bang(&mut self, mac: ast::Mac, span: Span, kind: AstFragmentKind) -> AstFragment {
         self.collect(kind, InvocationKind::Bang { mac: mac, ident: None, span: span })
     }
 
@@ -1020,8 +1047,8 @@ fn collect_attr(&mut self,
                     attr: Option<ast::Attribute>,
                     traits: Vec<Path>,
                     item: Annotatable,
-                    kind: ExpansionKind)
-                    -> Expansion {
+                    kind: AstFragmentKind)
+                    -> AstFragment {
         self.collect(kind, InvocationKind::Attr { attr, traits, item })
     }
 
@@ -1119,14 +1146,14 @@ fn fold_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
             // expansion will eat the attribute so it won't error later
             attr.as_ref().map(|a| self.cfg.maybe_emit_expr_attr_err(a));
 
-            // ExpansionKind::Expr requires the macro to emit an expression
-            return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)), ExpansionKind::Expr)
-                .make_expr();
+            // AstFragmentKind::Expr requires the macro to emit an expression
+            return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)),
+                                     AstFragmentKind::Expr).make_expr();
         }
 
         if let ast::ExprKind::Mac(mac) = expr.node {
             self.check_attributes(&expr.attrs);
-            self.collect_bang(mac, expr.span, ExpansionKind::Expr).make_expr()
+            self.collect_bang(mac, expr.span, AstFragmentKind::Expr).make_expr()
         } else {
             P(noop_fold_expr(expr, self))
         }
@@ -1143,13 +1170,13 @@ fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
             attr.as_ref().map(|a| self.cfg.maybe_emit_expr_attr_err(a));
 
             return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)),
-                                     ExpansionKind::OptExpr)
+                                     AstFragmentKind::OptExpr)
                 .make_opt_expr();
         }
 
         if let ast::ExprKind::Mac(mac) = expr.node {
             self.check_attributes(&expr.attrs);
-            self.collect_bang(mac, expr.span, ExpansionKind::OptExpr).make_opt_expr()
+            self.collect_bang(mac, expr.span, AstFragmentKind::OptExpr).make_opt_expr()
         } else {
             Some(P(noop_fold_expr(expr, self)))
         }
@@ -1163,7 +1190,7 @@ fn fold_pat(&mut self, pat: P<ast::Pat>) -> P<ast::Pat> {
         }
 
         pat.and_then(|pat| match pat.node {
-            PatKind::Mac(mac) => self.collect_bang(mac, pat.span, ExpansionKind::Pat).make_pat(),
+            PatKind::Mac(mac) => self.collect_bang(mac, pat.span, AstFragmentKind::Pat).make_pat(),
             _ => unreachable!(),
         })
     }
@@ -1187,7 +1214,7 @@ fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVector<ast::Stmt> {
 
             if attr.is_some() || !derives.is_empty() {
                 return self.collect_attr(attr, derives,
-                                         Annotatable::Stmt(P(stmt_)), ExpansionKind::Stmts)
+                                         Annotatable::Stmt(P(stmt_)), AstFragmentKind::Stmts)
                     .make_stmts();
             }
 
@@ -1197,7 +1224,7 @@ fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVector<ast::Stmt> {
         if let StmtKind::Mac(mac) = stmt.node {
             let (mac, style, attrs) = mac.into_inner();
             self.check_attributes(&attrs);
-            let mut placeholder = self.collect_bang(mac, stmt.span, ExpansionKind::Stmts)
+            let mut placeholder = self.collect_bang(mac, stmt.span, AstFragmentKind::Stmts)
                                         .make_stmts();
 
             // If this is a macro invocation with a semicolon, then apply that
@@ -1233,7 +1260,7 @@ fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
         let (attr, traits, mut item) = self.classify_item(item);
         if attr.is_some() || !traits.is_empty() {
             let item = Annotatable::Item(item);
-            return self.collect_attr(attr, traits, item, ExpansionKind::Items).make_items();
+            return self.collect_attr(attr, traits, item, AstFragmentKind::Items).make_items();
         }
 
         match item.node {
@@ -1241,7 +1268,7 @@ fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
                 self.check_attributes(&item.attrs);
                 item.and_then(|item| match item.node {
                     ItemKind::Mac(mac) => {
-                        self.collect(ExpansionKind::Items, InvocationKind::Bang {
+                        self.collect(AstFragmentKind::Items, InvocationKind::Bang {
                             mac,
                             ident: Some(item.ident),
                             span: item.span,
@@ -1317,7 +1344,7 @@ fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVector<ast::TraitIte
         let (attr, traits, item) = self.classify_item(item);
         if attr.is_some() || !traits.is_empty() {
             let item = Annotatable::TraitItem(P(item));
-            return self.collect_attr(attr, traits, item, ExpansionKind::TraitItems)
+            return self.collect_attr(attr, traits, item, AstFragmentKind::TraitItems)
                 .make_trait_items()
         }
 
@@ -1325,7 +1352,7 @@ fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVector<ast::TraitIte
             ast::TraitItemKind::Macro(mac) => {
                 let ast::TraitItem { attrs, span, .. } = item;
                 self.check_attributes(&attrs);
-                self.collect_bang(mac, span, ExpansionKind::TraitItems).make_trait_items()
+                self.collect_bang(mac, span, AstFragmentKind::TraitItems).make_trait_items()
             }
             _ => fold::noop_fold_trait_item(item, self),
         }
@@ -1337,7 +1364,7 @@ fn fold_impl_item(&mut self, item: ast::ImplItem) -> SmallVector<ast::ImplItem>
         let (attr, traits, item) = self.classify_item(item);
         if attr.is_some() || !traits.is_empty() {
             let item = Annotatable::ImplItem(P(item));
-            return self.collect_attr(attr, traits, item, ExpansionKind::ImplItems)
+            return self.collect_attr(attr, traits, item, AstFragmentKind::ImplItems)
                 .make_impl_items();
         }
 
@@ -1345,7 +1372,7 @@ fn fold_impl_item(&mut self, item: ast::ImplItem) -> SmallVector<ast::ImplItem>
             ast::ImplItemKind::Macro(mac) => {
                 let ast::ImplItem { attrs, span, .. } = item;
                 self.check_attributes(&attrs);
-                self.collect_bang(mac, span, ExpansionKind::ImplItems).make_impl_items()
+                self.collect_bang(mac, span, AstFragmentKind::ImplItems).make_impl_items()
             }
             _ => fold::noop_fold_impl_item(item, self),
         }
@@ -1358,7 +1385,7 @@ fn fold_ty(&mut self, ty: P<ast::Ty>) -> P<ast::Ty> {
         };
 
         match ty.node {
-            ast::TyKind::Mac(mac) => self.collect_bang(mac, ty.span, ExpansionKind::Ty).make_ty(),
+            ast::TyKind::Mac(mac) => self.collect_bang(mac, ty.span, AstFragmentKind::Ty).make_ty(),
             _ => unreachable!(),
         }
     }
@@ -1386,7 +1413,7 @@ fn fold_foreign_item(&mut self,
             }
 
             let item = Annotatable::ForeignItem(P(foreign_item));
-            return self.collect_attr(attr, traits, item, ExpansionKind::ForeignItems)
+            return self.collect_attr(attr, traits, item, AstFragmentKind::ForeignItems)
                 .make_foreign_items();
         }
 
@@ -1398,7 +1425,7 @@ fn fold_foreign_item(&mut self,
                                  GateIssue::Language, explain);
             }
 
-            return self.collect_bang(mac, foreign_item.span, ExpansionKind::ForeignItems)
+            return self.collect_bang(mac, foreign_item.span, AstFragmentKind::ForeignItems)
                 .make_foreign_items();
         }
 
@@ -1569,11 +1596,6 @@ fn proc_macro_non_items = proc_macro_non_items,
 pub struct Marker(pub Mark);
 
 impl Folder for Marker {
-    fn fold_ident(&mut self, mut ident: Ident) -> Ident {
-        ident.span = ident.span.apply_mark(self.0);
-        ident
-    }
-
     fn new_span(&mut self, span: Span) -> Span {
         span.apply_mark(self.0)
     }
index 5c1c661fffd378cebd212feca0276f309b1e3135..968cf508edaaae102ff17ce5566b012204f702b5 100644 (file)
@@ -11,7 +11,7 @@
 use ast::{self, NodeId};
 use codemap::{DUMMY_SP, dummy_spanned};
 use ext::base::ExtCtxt;
-use ext::expand::{Expansion, ExpansionKind};
+use ext::expand::{AstFragment, AstFragmentKind};
 use ext::hygiene::Mark;
 use tokenstream::TokenStream;
 use fold::*;
@@ -22,7 +22,7 @@
 
 use std::collections::HashMap;
 
-pub fn placeholder(kind: ExpansionKind, id: ast::NodeId) -> Expansion {
+pub fn placeholder(kind: AstFragmentKind, id: ast::NodeId) -> AstFragment {
     fn mac_placeholder() -> ast::Mac {
         dummy_spanned(ast::Mac_ {
             path: ast::Path { span: DUMMY_SP, segments: Vec::new() },
@@ -43,35 +43,36 @@ fn mac_placeholder() -> ast::Mac {
     });
 
     match kind {
-        ExpansionKind::Expr => Expansion::Expr(expr_placeholder()),
-        ExpansionKind::OptExpr => Expansion::OptExpr(Some(expr_placeholder())),
-        ExpansionKind::Items => Expansion::Items(SmallVector::one(P(ast::Item {
+        AstFragmentKind::Expr => AstFragment::Expr(expr_placeholder()),
+        AstFragmentKind::OptExpr => AstFragment::OptExpr(Some(expr_placeholder())),
+        AstFragmentKind::Items => AstFragment::Items(SmallVector::one(P(ast::Item {
             id, span, ident, vis, attrs,
             node: ast::ItemKind::Mac(mac_placeholder()),
             tokens: None,
         }))),
-        ExpansionKind::TraitItems => Expansion::TraitItems(SmallVector::one(ast::TraitItem {
+        AstFragmentKind::TraitItems => AstFragment::TraitItems(SmallVector::one(ast::TraitItem {
             id, span, ident, attrs, generics,
             node: ast::TraitItemKind::Macro(mac_placeholder()),
             tokens: None,
         })),
-        ExpansionKind::ImplItems => Expansion::ImplItems(SmallVector::one(ast::ImplItem {
+        AstFragmentKind::ImplItems => AstFragment::ImplItems(SmallVector::one(ast::ImplItem {
             id, span, ident, vis, attrs, generics,
             node: ast::ImplItemKind::Macro(mac_placeholder()),
             defaultness: ast::Defaultness::Final,
             tokens: None,
         })),
-        ExpansionKind::ForeignItems => Expansion::ForeignItems(SmallVector::one(ast::ForeignItem {
-            id, span, ident, vis, attrs,
-            node: ast::ForeignItemKind::Macro(mac_placeholder()),
-        })),
-        ExpansionKind::Pat => Expansion::Pat(P(ast::Pat {
+        AstFragmentKind::ForeignItems =>
+            AstFragment::ForeignItems(SmallVector::one(ast::ForeignItem {
+                id, span, ident, vis, attrs,
+                node: ast::ForeignItemKind::Macro(mac_placeholder()),
+            })),
+        AstFragmentKind::Pat => AstFragment::Pat(P(ast::Pat {
             id, span, node: ast::PatKind::Mac(mac_placeholder()),
         })),
-        ExpansionKind::Ty => Expansion::Ty(P(ast::Ty {
+        AstFragmentKind::Ty => AstFragment::Ty(P(ast::Ty {
             id, span, node: ast::TyKind::Mac(mac_placeholder()),
         })),
-        ExpansionKind::Stmts => Expansion::Stmts(SmallVector::one({
+        AstFragmentKind::Stmts => AstFragment::Stmts(SmallVector::one({
             let mac = P((mac_placeholder(), ast::MacStmtStyle::Braces, ast::ThinVec::new()));
             ast::Stmt { id, span, node: ast::StmtKind::Mac(mac) }
         })),
@@ -79,7 +80,7 @@ fn mac_placeholder() -> ast::Mac {
 }
 
 pub struct PlaceholderExpander<'a, 'b: 'a> {
-    expansions: HashMap<ast::NodeId, Expansion>,
+    expanded_fragments: HashMap<ast::NodeId, AstFragment>,
     cx: &'a mut ExtCtxt<'b>,
     monotonic: bool,
 }
@@ -88,27 +89,27 @@ impl<'a, 'b> PlaceholderExpander<'a, 'b> {
     pub fn new(cx: &'a mut ExtCtxt<'b>, monotonic: bool) -> Self {
         PlaceholderExpander {
             cx,
-            expansions: HashMap::new(),
+            expanded_fragments: HashMap::new(),
             monotonic,
         }
     }
 
-    pub fn add(&mut self, id: ast::NodeId, expansion: Expansion, derives: Vec<Mark>) {
-        let mut expansion = expansion.fold_with(self);
-        if let Expansion::Items(mut items) = expansion {
+    pub fn add(&mut self, id: ast::NodeId, fragment: AstFragment, derives: Vec<Mark>) {
+        let mut fragment = fragment.fold_with(self);
+        if let AstFragment::Items(mut items) = fragment {
             for derive in derives {
                 match self.remove(NodeId::placeholder_from_mark(derive)) {
-                    Expansion::Items(derived_items) => items.extend(derived_items),
+                    AstFragment::Items(derived_items) => items.extend(derived_items),
                     _ => unreachable!(),
                 }
             }
-            expansion = Expansion::Items(items);
+            fragment = AstFragment::Items(items);
         }
-        self.expansions.insert(id, expansion);
+        self.expanded_fragments.insert(id, fragment);
     }
 
-    fn remove(&mut self, id: ast::NodeId) -> Expansion {
-        self.expansions.remove(&id).unwrap()
+    fn remove(&mut self, id: ast::NodeId) -> AstFragment {
+        self.expanded_fragments.remove(&id).unwrap()
     }
 }
 
@@ -159,18 +160,18 @@ fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
     }
 
     fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVector<ast::Stmt> {
-        let (style, mut expansion) = match stmt.node {
+        let (style, mut stmts) = match stmt.node {
             ast::StmtKind::Mac(mac) => (mac.1, self.remove(stmt.id).make_stmts()),
             _ => return noop_fold_stmt(stmt, self),
         };
 
         if style == ast::MacStmtStyle::Semicolon {
-            if let Some(stmt) = expansion.pop() {
-                expansion.push(stmt.add_trailing_semicolon());
+            if let Some(stmt) = stmts.pop() {
+                stmts.push(stmt.add_trailing_semicolon());
             }
         }
 
-        expansion
+        stmts
     }
 
     fn fold_pat(&mut self, pat: P<ast::Pat>) -> P<ast::Pat> {
index 2e6d590c333cf562ae1bbc187258012e6ffb2a05..4ee5357f4766cc1186d36299a0e78f19e2d47d5e 100644 (file)
@@ -13,7 +13,7 @@
 use edition::Edition;
 use ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension};
 use ext::base::{NormalTT, TTMacroExpander};
-use ext::expand::{Expansion, ExpansionKind};
+use ext::expand::{AstFragment, AstFragmentKind};
 use ext::tt::macro_parser::{Success, Error, Failure};
 use ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
 use ext::tt::macro_parser::{parse, parse_failure_msg};
@@ -43,21 +43,21 @@ pub struct ParserAnyMacro<'a> {
 }
 
 impl<'a> ParserAnyMacro<'a> {
-    pub fn make(mut self: Box<ParserAnyMacro<'a>>, kind: ExpansionKind) -> Expansion {
+    pub fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
         let ParserAnyMacro { site_span, macro_ident, ref mut parser } = *self;
-        let expansion = panictry!(parser.parse_expansion(kind, true));
+        let fragment = panictry!(parser.parse_ast_fragment(kind, true));
 
         // We allow semicolons at the end of expressions -- e.g. the semicolon in
         // `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`,
         // but `m!()` is allowed in expression positions (c.f. issue #34706).
-        if kind == ExpansionKind::Expr && parser.token == token::Semi {
+        if kind == AstFragmentKind::Expr && parser.token == token::Semi {
             parser.bump();
         }
 
         // Make sure we don't have any tokens left to parse so we don't silently drop anything.
         let path = ast::Path::from_ident(macro_ident.with_span_pos(site_span));
         parser.ensure_complete_parse(&path, kind.name(), site_span);
-        expansion
+        fragment
     }
 }
 
index a2ea6a214841e71ca1d883b252a8114ec1f852d8..51d7a2369954424173e918b1dd8b3a91d4d63314 100644 (file)
@@ -29,7 +29,6 @@
 use ast::{self, NodeId, PatKind, RangeEnd};
 use attr;
 use edition::{ALL_EDITIONS, Edition};
-use codemap::Spanned;
 use syntax_pos::{Span, DUMMY_SP};
 use errors::{DiagnosticBuilder, Handler, FatalError};
 use visit::{self, FnKind, Visitor};
@@ -309,7 +308,7 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // Declarative macros 2.0 (`macro`).
     (active, decl_macro, "1.17.0", Some(39412), None),
 
-    // Allows #[link(kind="static-nobundle"...]
+    // Allows #[link(kind="static-nobundle"...)]
     (active, static_nobundle, "1.16.0", Some(37403), None),
 
     // `extern "msp430-interrupt" fn()`
@@ -459,6 +458,9 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // Scoped attributes
     (active, tool_attributes, "1.25.0", Some(44690), None),
 
+    // allow irrefutable patterns in if-let and while-let statements (RFC 2086)
+    (active, irrefutable_let_patterns, "1.27.0", Some(44495), None),
+
     // Allows use of the :literal macro fragment specifier (RFC 1576)
     (active, macro_literal_matcher, "1.27.0", Some(35625), None),
 
@@ -468,12 +470,14 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // 'a: { break 'a; }
     (active, label_break_value, "1.28.0", Some(48594), None),
 
-
     // #[panic_implementation]
     (active, panic_implementation, "1.28.0", Some(44489), None),
 
     // #[doc(keyword = "...")]
     (active, doc_keyword, "1.28.0", Some(51315), None),
+
+    // Allows async and await syntax
+    (active, async_await, "1.28.0", Some(50547), None),
 );
 
 declare_features! (
@@ -1721,6 +1725,12 @@ fn visit_expr(&mut self, e: &'a ast::Expr) {
                                     "labels on blocks are unstable");
                 }
             }
+            ast::ExprKind::Closure(_, ast::IsAsync::Async(_), ..) => {
+                gate_feature_post!(&self, async_await, e.span, "async closures are unstable");
+            }
+            ast::ExprKind::Async(..) => {
+                gate_feature_post!(&self, async_await, e.span, "async blocks are unstable");
+            }
             _ => {}
         }
         visit::walk_expr(self, e);
@@ -1760,20 +1770,24 @@ fn visit_fn(&mut self,
                 fn_decl: &'a ast::FnDecl,
                 span: Span,
                 _node_id: NodeId) {
-        // check for const fn declarations
-        if let FnKind::ItemFn(_, _, Spanned { node: ast::Constness::Const, .. }, _, _, _) =
-            fn_kind {
-            gate_feature_post!(&self, const_fn, span, "const fn is unstable");
-        }
-        // stability of const fn methods are covered in
-        // visit_trait_item and visit_impl_item below; this is
-        // because default methods don't pass through this
-        // point.
-
         match fn_kind {
-            FnKind::ItemFn(_, _, _, abi, _, _) |
-            FnKind::Method(_, &ast::MethodSig { abi, .. }, _, _) => {
-                self.check_abi(abi, span);
+            FnKind::ItemFn(_, header, _, _) => {
+                // check for const fn and async fn declarations
+                if header.asyncness.is_async() {
+                    gate_feature_post!(&self, async_await, span, "async fn is unstable");
+                }
+                if header.constness.node == ast::Constness::Const {
+                    gate_feature_post!(&self, const_fn, span, "const fn is unstable");
+                }
+                // stability of const fn methods are covered in
+                // visit_trait_item and visit_impl_item below; this is
+                // because default methods don't pass through this
+                // point.
+
+                self.check_abi(header.abi, span);
+            }
+            FnKind::Method(_, sig, _, _) => {
+                self.check_abi(sig.header.abi, span);
             }
             _ => {}
         }
@@ -1784,9 +1798,9 @@ fn visit_trait_item(&mut self, ti: &'a ast::TraitItem) {
         match ti.node {
             ast::TraitItemKind::Method(ref sig, ref block) => {
                 if block.is_none() {
-                    self.check_abi(sig.abi, ti.span);
+                    self.check_abi(sig.header.abi, ti.span);
                 }
-                if sig.constness.node == ast::Constness::Const {
+                if sig.header.constness.node == ast::Constness::Const {
                     gate_feature_post!(&self, const_fn, ti.span, "const fn is unstable");
                 }
             }
@@ -1797,7 +1811,7 @@ fn visit_trait_item(&mut self, ti: &'a ast::TraitItem) {
                     gate_feature_post!(&self, associated_type_defaults, ti.span,
                                        "associated type defaults are unstable");
                 }
-                if ti.generics.is_parameterized() {
+                if !ti.generics.params.is_empty() {
                     gate_feature_post!(&self, generic_associated_types, ti.span,
                                        "generic associated types are unstable");
                 }
@@ -1820,11 +1834,11 @@ fn visit_impl_item(&mut self, ii: &'a ast::ImplItem) {
 
         match ii.node {
             ast::ImplItemKind::Method(ref sig, _) => {
-                if sig.constness.node == ast::Constness::Const {
+                if sig.header.constness.node == ast::Constness::Const {
                     gate_feature_post!(&self, const_fn, ii.span, "const fn is unstable");
                 }
             }
-            ast::ImplItemKind::Type(_) if ii.generics.is_parameterized() => {
+            ast::ImplItemKind::Type(_) if !ii.generics.params.is_empty() => {
                 gate_feature_post!(&self, generic_associated_types, ii.span,
                                    "generic associated types are unstable");
             }
index 8544ef330dc33bb21ba046390c2a761561d842c0..ffea713f4ec76a359082178993b6fa09e1b5796e 100644 (file)
@@ -76,6 +76,10 @@ fn fold_item_simple(&mut self, i: Item) -> Item {
         noop_fold_item_simple(i, self)
     }
 
+    fn fold_fn_header(&mut self, header: FnHeader) -> FnHeader {
+        noop_fold_fn_header(header, self)
+    }
+
     fn fold_struct_field(&mut self, sf: StructField) -> StructField {
         noop_fold_struct_field(sf, self)
     }
@@ -132,10 +136,21 @@ fn fold_exprs(&mut self, es: Vec<P<Expr>>) -> Vec<P<Expr>> {
         noop_fold_exprs(es, self)
     }
 
+    fn fold_generic_arg(&mut self, arg: GenericArg) -> GenericArg {
+        match arg {
+            GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.fold_lifetime(lt)),
+            GenericArg::Type(ty) => GenericArg::Type(self.fold_ty(ty)),
+        }
+    }
+
     fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> {
         noop_fold_ty(t, self)
     }
 
+    fn fold_lifetime(&mut self, l: Lifetime) -> Lifetime {
+        noop_fold_lifetime(l, self)
+    }
+
     fn fold_ty_binding(&mut self, t: TypeBinding) -> TypeBinding {
         noop_fold_ty_binding(t, self)
     }
@@ -172,18 +187,18 @@ fn fold_qpath(&mut self, qs: Option<QSelf>, p: Path) -> (Option<QSelf>, Path) {
         noop_fold_qpath(qs, p, self)
     }
 
-    fn fold_path_parameters(&mut self, p: PathParameters) -> PathParameters {
-        noop_fold_path_parameters(p, self)
+    fn fold_generic_args(&mut self, p: GenericArgs) -> GenericArgs {
+        noop_fold_generic_args(p, self)
     }
 
-    fn fold_angle_bracketed_parameter_data(&mut self, p: AngleBracketedParameterData)
-                                           -> AngleBracketedParameterData
+    fn fold_angle_bracketed_parameter_data(&mut self, p: AngleBracketedArgs)
+                                           -> AngleBracketedArgs
     {
         noop_fold_angle_bracketed_parameter_data(p, self)
     }
 
-    fn fold_parenthesized_parameter_data(&mut self, p: ParenthesizedParameterData)
-                                         -> ParenthesizedParameterData
+    fn fold_parenthesized_parameter_data(&mut self, p: ParenthesisedArgs)
+                                         -> ParenthesisedArgs
     {
         noop_fold_parenthesized_parameter_data(p, self)
     }
@@ -233,10 +248,6 @@ fn fold_variant_data(&mut self, vdata: VariantData) -> VariantData {
         noop_fold_variant_data(vdata, self)
     }
 
-    fn fold_ty_param(&mut self, tp: TyParam) -> TyParam {
-        noop_fold_ty_param(tp, self)
-    }
-
     fn fold_generic_param(&mut self, param: GenericParam) -> GenericParam {
         noop_fold_generic_param(param, self)
     }
@@ -261,18 +272,16 @@ fn fold_interpolated(&mut self, nt: token::Nonterminal) -> token::Nonterminal {
         noop_fold_interpolated(nt, self)
     }
 
-    fn fold_opt_bounds(&mut self, b: Option<TyParamBounds>)
-                       -> Option<TyParamBounds> {
+    fn fold_opt_bounds(&mut self, b: Option<GenericBounds>) -> Option<GenericBounds> {
         noop_fold_opt_bounds(b, self)
     }
 
-    fn fold_bounds(&mut self, b: TyParamBounds)
-                       -> TyParamBounds {
+    fn fold_bounds(&mut self, b: GenericBounds) -> GenericBounds {
         noop_fold_bounds(b, self)
     }
 
-    fn fold_ty_param_bound(&mut self, tpb: TyParamBound) -> TyParamBound {
-        noop_fold_ty_param_bound(tpb, self)
+    fn fold_param_bound(&mut self, tpb: GenericBound) -> GenericBound {
+        noop_fold_param_bound(tpb, self)
     }
 
     fn fold_mt(&mut self, mt: MutTy) -> MutTy {
@@ -385,10 +394,10 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
                 TyKind::Typeof(fld.fold_anon_const(expr))
             }
             TyKind::TraitObject(bounds, syntax) => {
-                TyKind::TraitObject(bounds.move_map(|b| fld.fold_ty_param_bound(b)), syntax)
+                TyKind::TraitObject(bounds.move_map(|b| fld.fold_param_bound(b)), syntax)
             }
             TyKind::ImplTrait(bounds) => {
-                TyKind::ImplTrait(bounds.move_map(|b| fld.fold_ty_param_bound(b)))
+                TyKind::ImplTrait(bounds.move_map(|b| fld.fold_param_bound(b)))
             }
             TyKind::Mac(mac) => {
                 TyKind::Mac(fld.fold_mac(mac))
@@ -433,9 +442,9 @@ pub fn noop_fold_usize<T: Folder>(i: usize, _: &mut T) -> usize {
 
 pub fn noop_fold_path<T: Folder>(Path { segments, span }: Path, fld: &mut T) -> Path {
     Path {
-        segments: segments.move_map(|PathSegment {ident, parameters}| PathSegment {
+        segments: segments.move_map(|PathSegment { ident, args }| PathSegment {
             ident: fld.fold_ident(ident),
-            parameters: parameters.map(|ps| ps.map(|ps| fld.fold_path_parameters(ps))),
+            args: args.map(|args| args.map(|args| fld.fold_generic_args(args))),
         }),
         span: fld.new_span(span)
     }
@@ -454,36 +463,40 @@ pub fn noop_fold_qpath<T: Folder>(qself: Option<QSelf>,
     (qself, fld.fold_path(path))
 }
 
-pub fn noop_fold_path_parameters<T: Folder>(path_parameters: PathParameters, fld: &mut T)
-                                            -> PathParameters
+pub fn noop_fold_generic_args<T: Folder>(generic_args: GenericArgs, fld: &mut T) -> GenericArgs
 {
-    match path_parameters {
-        PathParameters::AngleBracketed(data) =>
-            PathParameters::AngleBracketed(fld.fold_angle_bracketed_parameter_data(data)),
-        PathParameters::Parenthesized(data) =>
-            PathParameters::Parenthesized(fld.fold_parenthesized_parameter_data(data)),
+    match generic_args {
+        GenericArgs::AngleBracketed(data) => {
+            GenericArgs::AngleBracketed(fld.fold_angle_bracketed_parameter_data(data))
+        }
+        GenericArgs::Parenthesized(data) => {
+            GenericArgs::Parenthesized(fld.fold_parenthesized_parameter_data(data))
+        }
     }
 }
 
-pub fn noop_fold_angle_bracketed_parameter_data<T: Folder>(data: AngleBracketedParameterData,
+pub fn noop_fold_angle_bracketed_parameter_data<T: Folder>(data: AngleBracketedArgs,
                                                            fld: &mut T)
-                                                           -> AngleBracketedParameterData
+                                                           -> AngleBracketedArgs
 {
-    let AngleBracketedParameterData { lifetimes, types, bindings, span } = data;
-    AngleBracketedParameterData { lifetimes: lifetimes.move_map(|l| noop_fold_lifetime(l, fld)),
-                                  types: types.move_map(|ty| fld.fold_ty(ty)),
-                                  bindings: bindings.move_map(|b| fld.fold_ty_binding(b)),
-                                  span: fld.new_span(span) }
+    let AngleBracketedArgs { args, bindings, span } = data;
+    AngleBracketedArgs {
+        args: args.move_map(|arg| fld.fold_generic_arg(arg)),
+        bindings: bindings.move_map(|b| fld.fold_ty_binding(b)),
+        span: fld.new_span(span)
+    }
 }
 
-pub fn noop_fold_parenthesized_parameter_data<T: Folder>(data: ParenthesizedParameterData,
+pub fn noop_fold_parenthesized_parameter_data<T: Folder>(data: ParenthesisedArgs,
                                                          fld: &mut T)
-                                                         -> ParenthesizedParameterData
+                                                         -> ParenthesisedArgs
 {
-    let ParenthesizedParameterData { inputs, output, span } = data;
-    ParenthesizedParameterData { inputs: inputs.move_map(|ty| fld.fold_ty(ty)),
-                                 output: output.map(|ty| fld.fold_ty(ty)),
-                                 span: fld.new_span(span) }
+    let ParenthesisedArgs { inputs, output, span } = data;
+    ParenthesisedArgs {
+        inputs: inputs.move_map(|ty| fld.fold_ty(ty)),
+        output: output.map(|ty| fld.fold_ty(ty)),
+        span: fld.new_span(span)
+    }
 }
 
 pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> {
@@ -667,47 +680,33 @@ pub fn noop_fold_fn_decl<T: Folder>(decl: P<FnDecl>, fld: &mut T) -> P<FnDecl> {
     })
 }
 
-pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T)
-                                   -> TyParamBound
-                                   where T: Folder {
-    match tpb {
-        TraitTyParamBound(ty, modifier) => TraitTyParamBound(fld.fold_poly_trait_ref(ty), modifier),
-        RegionTyParamBound(lifetime) => RegionTyParamBound(noop_fold_lifetime(lifetime, fld)),
-    }
-}
-
-pub fn noop_fold_ty_param<T: Folder>(tp: TyParam, fld: &mut T) -> TyParam {
-    let TyParam {attrs, id, ident, bounds, default} = tp;
-    let attrs: Vec<_> = attrs.into();
-    TyParam {
-        attrs: attrs.into_iter()
-            .flat_map(|x| fld.fold_attribute(x).into_iter())
-            .collect::<Vec<_>>()
-            .into(),
-        id: fld.new_id(id),
-        ident: fld.fold_ident(ident),
-        bounds: fld.fold_bounds(bounds),
-        default: default.map(|x| fld.fold_ty(x)),
+pub fn noop_fold_param_bound<T>(pb: GenericBound, fld: &mut T) -> GenericBound where T: Folder {
+    match pb {
+        GenericBound::Trait(ty, modifier) => {
+            GenericBound::Trait(fld.fold_poly_trait_ref(ty), modifier)
+        }
+        GenericBound::Outlives(lifetime) => {
+            GenericBound::Outlives(noop_fold_lifetime(lifetime, fld))
+        }
     }
 }
 
 pub fn noop_fold_generic_param<T: Folder>(param: GenericParam, fld: &mut T) -> GenericParam {
-    match param {
-        GenericParam::Lifetime(l) => {
-            let attrs: Vec<_> = l.attrs.into();
-            GenericParam::Lifetime(LifetimeDef {
-                attrs: attrs.into_iter()
+    let attrs: Vec<_> = param.attrs.into();
+    GenericParam {
+        ident: fld.fold_ident(param.ident),
+        id: fld.new_id(param.id),
+        attrs: attrs.into_iter()
                     .flat_map(|x| fld.fold_attribute(x).into_iter())
                     .collect::<Vec<_>>()
                     .into(),
-                lifetime: Lifetime {
-                    id: fld.new_id(l.lifetime.id),
-                    ident: fld.fold_ident(l.lifetime.ident),
-                },
-                bounds: l.bounds.move_map(|l| noop_fold_lifetime(l, fld)),
-            })
+        bounds: param.bounds.move_map(|l| noop_fold_param_bound(l, fld)),
+        kind: match param.kind {
+            GenericParamKind::Lifetime => GenericParamKind::Lifetime,
+            GenericParamKind::Type { default } => GenericParamKind::Type {
+                default: default.map(|ty| fld.fold_ty(ty))
+            }
         }
-        GenericParam::Type(t) => GenericParam::Type(fld.fold_ty_param(t)),
     }
 }
 
@@ -765,7 +764,7 @@ pub fn noop_fold_where_predicate<T: Folder>(
             ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
                 bound_generic_params: fld.fold_generic_params(bound_generic_params),
                 bounded_ty: fld.fold_ty(bounded_ty),
-                bounds: bounds.move_map(|x| fld.fold_ty_param_bound(x)),
+                bounds: bounds.move_map(|x| fld.fold_param_bound(x)),
                 span: fld.new_span(span)
             })
         }
@@ -775,7 +774,7 @@ pub fn noop_fold_where_predicate<T: Folder>(
             ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
                 span: fld.new_span(span),
                 lifetime: noop_fold_lifetime(lifetime, fld),
-                bounds: bounds.move_map(|bound| noop_fold_lifetime(bound, fld))
+                bounds: bounds.move_map(|bound| noop_fold_param_bound(bound, fld))
             })
         }
         ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{id,
@@ -854,14 +853,14 @@ pub fn noop_fold_mt<T: Folder>(MutTy {ty, mutbl}: MutTy, folder: &mut T) -> MutT
     }
 }
 
-pub fn noop_fold_opt_bounds<T: Folder>(b: Option<TyParamBounds>, folder: &mut T)
-                                       -> Option<TyParamBounds> {
+pub fn noop_fold_opt_bounds<T: Folder>(b: Option<GenericBounds>, folder: &mut T)
+                                       -> Option<GenericBounds> {
     b.map(|bounds| folder.fold_bounds(bounds))
 }
 
-fn noop_fold_bounds<T: Folder>(bounds: TyParamBounds, folder: &mut T)
-                          -> TyParamBounds {
-    bounds.move_map(|bound| folder.fold_ty_param_bound(bound))
+fn noop_fold_bounds<T: Folder>(bounds: GenericBounds, folder: &mut T)
+                          -> GenericBounds {
+    bounds.move_map(|bound| folder.fold_param_bound(bound))
 }
 
 pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
@@ -886,11 +885,12 @@ pub fn noop_fold_item_kind<T: Folder>(i: ItemKind, folder: &mut T) -> ItemKind {
         ItemKind::Const(t, e) => {
             ItemKind::Const(folder.fold_ty(t), folder.fold_expr(e))
         }
-        ItemKind::Fn(decl, unsafety, constness, abi, generics, body) => {
+        ItemKind::Fn(decl, header, generics, body) => {
             let generics = folder.fold_generics(generics);
+            let header = folder.fold_fn_header(header);
             let decl = folder.fold_fn_decl(decl);
             let body = folder.fold_block(body);
-            ItemKind::Fn(decl, unsafety, constness, abi, generics, body)
+            ItemKind::Fn(decl, header, generics, body)
         }
         ItemKind::Mod(m) => ItemKind::Mod(folder.fold_mod(m)),
         ItemKind::ForeignMod(nm) => ItemKind::ForeignMod(folder.fold_foreign_mod(nm)),
@@ -995,6 +995,14 @@ pub fn noop_fold_impl_item<T: Folder>(i: ImplItem, folder: &mut T)
     })
 }
 
+pub fn noop_fold_fn_header<T: Folder>(mut header: FnHeader, folder: &mut T) -> FnHeader {
+    header.asyncness = match header.asyncness {
+        IsAsync::Async(node_id) => IsAsync::Async(folder.new_id(node_id)),
+        IsAsync::NotAsync => IsAsync::NotAsync,
+    };
+    header
+}
+
 pub fn noop_fold_mod<T: Folder>(Mod {inner, items}: Mod, folder: &mut T) -> Mod {
     Mod {
         inner: folder.new_span(inner),
@@ -1087,9 +1095,7 @@ pub fn noop_fold_foreign_item_simple<T: Folder>(ni: ForeignItem, folder: &mut T)
 
 pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> MethodSig {
     MethodSig {
-        abi: sig.abi,
-        unsafety: sig.unsafety,
-        constness: sig.constness,
+        header: folder.fold_fn_header(sig.header),
         decl: folder.fold_fn_decl(sig.decl)
     }
 }
@@ -1184,8 +1190,8 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
                 ExprKind::MethodCall(
                     PathSegment {
                         ident: folder.fold_ident(seg.ident),
-                        parameters: seg.parameters.map(|ps| {
-                            ps.map(|ps| folder.fold_path_parameters(ps))
+                        args: seg.args.map(|args| {
+                            args.map(|args| folder.fold_generic_args(args))
                         }),
                     },
                     folder.fold_exprs(args))
@@ -1242,8 +1248,13 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
                 ExprKind::Match(folder.fold_expr(expr),
                           arms.move_map(|x| folder.fold_arm(x)))
             }
-            ExprKind::Closure(capture_clause, movability, decl, body, span) => {
+            ExprKind::Closure(capture_clause, asyncness, movability, decl, body, span) => {
+                let asyncness = match asyncness {
+                    IsAsync::Async(node_id) => IsAsync::Async(folder.new_id(node_id)),
+                    IsAsync::NotAsync => IsAsync::NotAsync,
+                };
                 ExprKind::Closure(capture_clause,
+                                  asyncness,
                                   movability,
                                   folder.fold_fn_decl(decl),
                                   folder.fold_expr(body),
@@ -1253,6 +1264,9 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
                 ExprKind::Block(folder.fold_block(blk),
                                 opt_label.map(|label| folder.fold_label(label)))
             }
+            ExprKind::Async(capture_clause, node_id, body) => {
+                ExprKind::Async(capture_clause, folder.new_id(node_id), folder.fold_block(body))
+            }
             ExprKind::Assign(el, er) => {
                 ExprKind::Assign(folder.fold_expr(el), folder.fold_expr(er))
             }
index 2ee14bd61c28532c3750c52f7b124562cbf340b8..1ace9193dc69dafaf675a0fb9e9c270d6d77a039 100644 (file)
        html_root_url = "https://doc.rust-lang.org/nightly/",
        test(attr(deny(warnings))))]
 
-#![feature(unicode_internals)]
-#![feature(rustc_diagnostic_macros)]
-#![feature(slice_sort_by_cached_key)]
 #![feature(const_atomic_usize_new)]
+#![feature(crate_visibility_modifier)]
+#![feature(macro_at_most_once_rep)]
 #![feature(rustc_attrs)]
+#![feature(rustc_diagnostic_macros)]
+#![feature(slice_sort_by_cached_key)]
 #![feature(str_escape)]
-#![feature(crate_visibility_modifier)]
+#![feature(unicode_internals)]
 
 #![recursion_limit="256"]
 
index 0050434d42e3f41060be582896f1dd26be0139a1..cce8da1dcbd53f9291aa08bab5d6e032920e9938 100644 (file)
@@ -294,7 +294,7 @@ fn char_lit(lit: &str, diag: Option<(Span, &Handler)>) -> (char, isize) {
 
 /// Parse a string representing a string literal into its final form. Does
 /// unescaping.
-fn str_lit(lit: &str, diag: Option<(Span, &Handler)>) -> String {
+pub fn str_lit(lit: &str, diag: Option<(Span, &Handler)>) -> String {
     debug!("str_lit: given {}", lit.escape_default());
     let mut res = String::with_capacity(lit.len());
 
@@ -928,12 +928,15 @@ fn parser_done(p: Parser){
                                     output: ast::FunctionRetTy::Default(sp(15, 15)),
                                     variadic: false
                                 }),
-                                        ast::Unsafety::Normal,
-                                        Spanned {
-                                            span: sp(0,2),
-                                            node: ast::Constness::NotConst,
+                                        ast::FnHeader {
+                                            unsafety: ast::Unsafety::Normal,
+                                            asyncness: ast::IsAsync::NotAsync,
+                                            constness: Spanned {
+                                                span: sp(0,2),
+                                                node: ast::Constness::NotConst,
+                                            },
+                                            abi: Abi::Rust,
                                         },
-                                        Abi::Rust,
                                         ast::Generics{
                                             params: Vec::new(),
                                             where_clause: ast::WhereClause {
index 1735951da2f34638008e06bd45f482dc2c1ad6c0..955bdbdcf917765d8620b4a730070b1da4812d2e 100644 (file)
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 use rustc_target::spec::abi::{self, Abi};
-use ast::{AngleBracketedParameterData, ParenthesizedParameterData, AttrStyle, BareFnTy};
-use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
+use ast::{AngleBracketedArgs, ParenthesisedArgs, AttrStyle, BareFnTy};
+use ast::{GenericBound, TraitBoundModifier};
 use ast::Unsafety;
 use ast::{Mod, AnonConst, Arg, Arm, Attribute, BindingMode, TraitItemKind};
 use ast::Block;
 use ast::Defaultness;
 use ast::EnumDef;
 use ast::{Expr, ExprKind, RangeLimits};
-use ast::{Field, FnDecl};
+use ast::{Field, FnDecl, FnHeader};
 use ast::{ForeignItem, ForeignItemKind, FunctionRetTy};
-use ast::GenericParam;
-use ast::{Ident, ImplItem, IsAuto, Item, ItemKind};
-use ast::{Label, Lifetime, LifetimeDef, Lit, LitKind};
+use ast::{GenericParam, GenericParamKind};
+use ast::GenericArg;
+use ast::{Ident, ImplItem, IsAsync, IsAuto, Item, ItemKind};
+use ast::{Label, Lifetime, Lit, LitKind};
 use ast::Local;
 use ast::MacStmtStyle;
 use ast::{Mac, Mac_, MacDelimiter};
 use ast::StrStyle;
 use ast::SelfKind;
 use ast::{TraitItem, TraitRef, TraitObjectSyntax};
-use ast::{Ty, TyKind, TypeBinding, TyParam, TyParamBounds};
+use ast::{Ty, TyKind, TypeBinding, GenericBounds};
 use ast::{Visibility, VisibilityKind, WhereClause, CrateSugar};
 use ast::{UseTree, UseTreeKind};
 use ast::{BinOpKind, UnOp};
 use ast::{RangeEnd, RangeSyntax};
 use {ast, attr};
 use codemap::{self, CodeMap, Spanned, respan};
-use syntax_pos::{self, Span, MultiSpan, BytePos, FileName, DUMMY_SP};
+use syntax_pos::{self, Span, MultiSpan, BytePos, FileName, DUMMY_SP, edition::Edition};
 use errors::{self, Applicability, DiagnosticBuilder};
 use parse::{self, SeqSep, classify, token};
 use parse::lexer::TokenAndSpan;
@@ -637,7 +638,26 @@ pub fn expect(&mut self, t: &token::Token) -> PResult<'a,  ()> {
                 let mut err = self.fatal(&format!("expected `{}`, found `{}`",
                                                   token_str,
                                                   this_token_str));
-                err.span_label(self.span, format!("expected `{}`", token_str));
+
+                let sp = if self.token == token::Token::Eof {
+                    // EOF, don't want to point at the following char, but rather the last token
+                    self.prev_span
+                } else {
+                    self.sess.codemap().next_point(self.prev_span)
+                };
+                let label_exp = format!("expected `{}`", token_str);
+                let cm = self.sess.codemap();
+                match (cm.lookup_line(self.span.lo()), cm.lookup_line(sp.lo())) {
+                    (Ok(ref a), Ok(ref b)) if a.line == b.line => {
+                        // When the spans are in the same line, it means that the only content
+                        // between them is whitespace, point only at the found token.
+                        err.span_label(self.span, label_exp);
+                    }
+                    _ => {
+                        err.span_label(sp, label_exp);
+                        err.span_label(self.span, "unexpected token");
+                    }
+                }
                 Err(err)
             }
         } else {
@@ -756,6 +776,9 @@ fn expected_ident_found(&self) -> DiagnosticBuilder<'a> {
             err.span_label(self.span, format!("expected identifier, found {}", token_descr));
         } else {
             err.span_label(self.span, "expected identifier");
+            if self.token == token::Comma && self.look_ahead(1, |t| t.is_ident()) {
+                err.span_suggestion(self.span, "remove this comma", "".into());
+            }
         }
         err
     }
@@ -1037,7 +1060,7 @@ pub fn parse_seq_to_end<T, F>(&mut self,
     /// Parse a sequence, not including the closing delimiter. The function
     /// f must consume tokens until reaching the next separator or
     /// closing bracket.
-    fn parse_seq_to_before_end<T, F>(&mut self,
+    pub fn parse_seq_to_before_end<T, F>(&mut self,
                                          ket: &token::Token,
                                          sep: SeqSep,
                                          f: F)
@@ -1204,14 +1227,6 @@ pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilde
     fn span_fatal_err<S: Into<MultiSpan>>(&self, sp: S, err: Error) -> DiagnosticBuilder<'a> {
         err.span_err(sp, self.diagnostic())
     }
-    fn span_fatal_help<S: Into<MultiSpan>>(&self,
-                                            sp: S,
-                                            m: &str,
-                                            help: &str) -> DiagnosticBuilder<'a> {
-        let mut err = self.sess.span_diagnostic.struct_span_fatal(sp, m);
-        err.help(help);
-        err
-    }
     fn bug(&self, m: &str) -> ! {
         self.sess.span_diagnostic.span_bug(self.span, m)
     }
@@ -1245,8 +1260,7 @@ fn token_is_bare_fn_keyword(&mut self) -> bool {
     }
 
     /// parse a TyKind::BareFn type:
-    fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>)
-                            -> PResult<'a, TyKind> {
+    fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>) -> PResult<'a, TyKind> {
         /*
 
         [unsafe] [extern "ABI"] fn (S) -> T
@@ -1282,6 +1296,15 @@ fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>)
         })))
     }
 
+    /// Parse asyncness: `async` or nothing
+    fn parse_asyncness(&mut self) -> IsAsync {
+        if self.eat_keyword(keywords::Async) {
+            IsAsync::Async(ast::DUMMY_NODE_ID)
+        } else {
+            IsAsync::NotAsync
+        }
+    }
+
     /// Parse unsafety: `unsafe` or nothing.
     fn parse_unsafety(&mut self) -> Unsafety {
         if self.eat_keyword(keywords::Unsafe) {
@@ -1311,9 +1334,7 @@ fn parse_trait_item_(&mut self,
         let lo = self.span;
 
         let (name, node, generics) = if self.eat_keyword(keywords::Type) {
-            let (generics, TyParam {ident, bounds, default, ..}) =
-                self.parse_trait_item_assoc_ty(vec![])?;
-            (ident, TraitItemKind::Type(bounds, default), generics)
+            self.parse_trait_item_assoc_ty()?
         } else if self.is_const_item() {
             self.expect_keyword(keywords::Const)?;
             let ident = self.parse_ident()?;
@@ -1333,7 +1354,7 @@ fn parse_trait_item_(&mut self,
             // trait item macro.
             (keywords::Invalid.ident(), ast::TraitItemKind::Macro(mac), ast::Generics::default())
         } else {
-            let (constness, unsafety, abi) = self.parse_fn_front_matter()?;
+            let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
 
             let ident = self.parse_ident()?;
             let mut generics = self.parse_generics()?;
@@ -1347,10 +1368,13 @@ fn parse_trait_item_(&mut self,
             generics.where_clause = self.parse_where_clause()?;
 
             let sig = ast::MethodSig {
-                unsafety,
-                constness,
+                header: FnHeader {
+                    unsafety,
+                    constness,
+                    abi,
+                    asyncness,
+                },
                 decl: d,
-                abi,
             };
 
             let body = match self.token {
@@ -1446,7 +1470,7 @@ fn parse_ty_common(&mut self, allow_plus: bool, allow_qpath_recovery: bool)
                     TyKind::TraitObject(ref bounds, TraitObjectSyntax::None)
                             if maybe_bounds && bounds.len() == 1 && !trailing_plus => {
                         let path = match bounds[0] {
-                            TraitTyParamBound(ref pt, ..) => pt.trait_ref.path.clone(),
+                            GenericBound::Trait(ref pt, ..) => pt.trait_ref.path.clone(),
                             _ => self.bug("unexpected lifetime bound"),
                         };
                         self.parse_remaining_bounds(Vec::new(), path, lo, true)?
@@ -1511,7 +1535,7 @@ fn parse_ty_common(&mut self, allow_plus: bool, allow_qpath_recovery: bool)
             }
         } else if self.eat_keyword(keywords::Impl) {
             // Always parse bounds greedily for better error recovery.
-            let bounds = self.parse_ty_param_bounds()?;
+            let bounds = self.parse_generic_bounds()?;
             impl_dyn_multi = bounds.len() > 1 || self.prev_token_kind == PrevTokenKind::Plus;
             TyKind::ImplTrait(bounds)
         } else if self.check_keyword(keywords::Dyn) &&
@@ -1519,13 +1543,13 @@ fn parse_ty_common(&mut self, allow_plus: bool, allow_qpath_recovery: bool)
                                          !can_continue_type_after_non_fn_ident(t)) {
             self.bump(); // `dyn`
             // Always parse bounds greedily for better error recovery.
-            let bounds = self.parse_ty_param_bounds()?;
+            let bounds = self.parse_generic_bounds()?;
             impl_dyn_multi = bounds.len() > 1 || self.prev_token_kind == PrevTokenKind::Plus;
             TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn)
         } else if self.check(&token::Question) ||
                   self.check_lifetime() && self.look_ahead(1, |t| t.is_like_plus()) {
             // Bound list (trait object type)
-            TyKind::TraitObject(self.parse_ty_param_bounds_common(allow_plus)?,
+            TyKind::TraitObject(self.parse_generic_bounds_common(allow_plus)?,
                                 TraitObjectSyntax::None)
         } else if self.eat_lt() {
             // Qualified path
@@ -1568,10 +1592,10 @@ fn parse_ty_common(&mut self, allow_plus: bool, allow_qpath_recovery: bool)
     fn parse_remaining_bounds(&mut self, generic_params: Vec<GenericParam>, path: ast::Path,
                               lo: Span, parse_plus: bool) -> PResult<'a, TyKind> {
         let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_span));
-        let mut bounds = vec![TraitTyParamBound(poly_trait_ref, TraitBoundModifier::None)];
+        let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)];
         if parse_plus {
             self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
-            bounds.append(&mut self.parse_ty_param_bounds()?);
+            bounds.append(&mut self.parse_generic_bounds()?);
         }
         Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
     }
@@ -1596,7 +1620,7 @@ fn maybe_recover_from_bad_type_plus(&mut self, allow_plus: bool, ty: &Ty) -> PRe
         }
 
         self.bump(); // `+`
-        let bounds = self.parse_ty_param_bounds()?;
+        let bounds = self.parse_generic_bounds()?;
         let sum_span = ty.span.to(self.prev_span);
 
         let mut err = struct_span_err!(self.sess.span_diagnostic, sum_span, E0178,
@@ -1612,7 +1636,7 @@ fn maybe_recover_from_bad_type_plus(&mut self, allow_plus: bool, ty: &Ty) -> PRe
                     s.print_mutability(mut_ty.mutbl)?;
                     s.popen()?;
                     s.print_type(&mut_ty.ty)?;
-                    s.print_bounds(" +", &bounds)?;
+                    s.print_type_bounds(" +", &bounds)?;
                     s.pclose()
                 });
                 err.span_suggestion_with_applicability(
@@ -1894,7 +1918,7 @@ pub fn parse_path(&mut self, style: PathStyle) -> PResult<'a, ast::Path> {
                              -> PResult<'a, ast::Path> {
         maybe_whole!(self, NtPath, |path| {
             if style == PathStyle::Mod &&
-               path.segments.iter().any(|segment| segment.parameters.is_some()) {
+               path.segments.iter().any(|segment| segment.args.is_some()) {
                 self.diagnostic().span_err(path.span, "unexpected generic arguments in path");
             }
             path
@@ -1969,12 +1993,12 @@ fn parse_path_segment(&mut self, style: PathStyle, enable_warning: bool)
                                  .span_label(self.prev_span, "try removing `::`").emit();
             }
 
-            let parameters = if self.eat_lt() {
+            let args = if self.eat_lt() {
                 // `<'a, T, A = U>`
-                let (lifetimes, types, bindings) = self.parse_generic_args()?;
+                let (args, bindings) = self.parse_generic_args()?;
                 self.expect_gt()?;
                 let span = lo.to(self.prev_span);
-                AngleBracketedParameterData { lifetimes, types, bindings, span }.into()
+                AngleBracketedArgs { args, bindings, span }.into()
             } else {
                 // `(T, U) -> R`
                 self.bump(); // `(`
@@ -1990,10 +2014,10 @@ fn parse_path_segment(&mut self, style: PathStyle, enable_warning: bool)
                     None
                 };
                 let span = lo.to(self.prev_span);
-                ParenthesizedParameterData { inputs, output, span }.into()
+                ParenthesisedArgs { inputs, output, span }.into()
             };
 
-            PathSegment { ident, parameters }
+            PathSegment { ident, args }
         } else {
             // Generic arguments are not found.
             PathSegment::from_ident(ident)
@@ -2108,7 +2132,7 @@ fn mk_assign_op(&mut self, binop: ast::BinOp,
         ExprKind::AssignOp(binop, lhs, rhs)
     }
 
-    fn mk_mac_expr(&mut self, span: Span, m: Mac_, attrs: ThinVec<Attribute>) -> P<Expr> {
+    pub fn mk_mac_expr(&mut self, span: Span, m: Mac_, attrs: ThinVec<Attribute>) -> P<Expr> {
         P(Expr {
             id: ast::DUMMY_NODE_ID,
             node: ExprKind::Mac(codemap::Spanned {node: m, span: span}),
@@ -2246,6 +2270,15 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
                     hi = path.span;
                     return Ok(self.mk_expr(lo.to(hi), ExprKind::Path(Some(qself), path), attrs));
                 }
+                if self.span.edition() >= Edition::Edition2018 &&
+                    self.check_keyword(keywords::Async)
+                {
+                    if self.is_async_block() { // check for `async {` and `async move {`
+                        return self.parse_async_block(attrs);
+                    } else {
+                        return self.parse_lambda_expr(attrs);
+                    }
+                }
                 if self.check_keyword(keywords::Move) || self.check_keyword(keywords::Static) {
                     return self.parse_lambda_expr(attrs);
                 }
@@ -2437,8 +2470,14 @@ fn parse_struct_expr(&mut self, lo: Span, pth: ast::Path, mut attrs: ThinVec<Att
                 Err(mut e) => {
                     e.span_label(struct_sp, "while parsing this struct");
                     e.emit();
-                    self.recover_stmt();
-                    break;
+
+                    // If the next token is a comma, then try to parse
+                    // what comes next as additional fields, rather than
+                    // bailing out until next `}`.
+                    if self.token != token::Comma {
+                        self.recover_stmt();
+                        break;
+                    }
                 }
             }
 
@@ -2543,8 +2582,8 @@ fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Exp
             }
             _ => {
                 // Field access `expr.f`
-                if let Some(parameters) = segment.parameters {
-                    self.span_err(parameters.span(),
+                if let Some(args) = segment.args {
+                    self.span_err(args.span(),
                                   "field expressions may not have generic arguments");
                 }
 
@@ -3240,6 +3279,13 @@ fn parse_lambda_expr(&mut self,
         } else {
             Movability::Movable
         };
+        let asyncness = if self.span.edition() >= Edition::Edition2018
+            && self.eat_keyword(keywords::Async)
+        {
+            IsAsync::Async(ast::DUMMY_NODE_ID)
+        } else {
+            IsAsync::NotAsync
+        };
         let capture_clause = if self.eat_keyword(keywords::Move) {
             CaptureBy::Value
         } else {
@@ -3262,7 +3308,7 @@ fn parse_lambda_expr(&mut self,
 
         Ok(self.mk_expr(
             lo.to(body.span),
-            ExprKind::Closure(capture_clause, movability, decl, body, lo.to(decl_hi)),
+            ExprKind::Closure(capture_clause, asyncness, movability, decl, body, lo.to(decl_hi)),
             attrs))
     }
 
@@ -3340,6 +3386,24 @@ fn parse_loop_expr(&mut self, opt_label: Option<Label>,
         Ok(self.mk_expr(span, ExprKind::Loop(body, opt_label), attrs))
     }
 
+    /// Parse an `async move {...}` expression
+    pub fn parse_async_block(&mut self, mut attrs: ThinVec<Attribute>)
+        -> PResult<'a, P<Expr>>
+    {
+        let span_lo = self.span;
+        self.expect_keyword(keywords::Async)?;
+        let capture_clause = if self.eat_keyword(keywords::Move) {
+            CaptureBy::Value
+        } else {
+            CaptureBy::Ref
+        };
+        let (iattrs, body) = self.parse_inner_attrs_and_block()?;
+        attrs.extend(iattrs);
+        Ok(self.mk_expr(
+            span_lo.to(body.span),
+            ExprKind::Async(capture_clause, ast::DUMMY_NODE_ID, body), attrs))
+    }
+
     /// Parse a `do catch {...}` expression (`do catch` token already eaten)
     fn parse_catch_expr(&mut self, span_lo: Span, mut attrs: ThinVec<Attribute>)
         -> PResult<'a, P<Expr>>
@@ -4274,6 +4338,18 @@ fn parse_stmt_(&mut self, macro_legacy_warnings: bool) -> Option<Stmt> {
         })
     }
 
+    fn is_async_block(&mut self) -> bool {
+        self.token.is_keyword(keywords::Async) &&
+        (
+            ( // `async move {`
+                self.look_ahead(1, |t| t.is_keyword(keywords::Move)) &&
+                self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace))
+            ) || ( // `async {`
+                self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace))
+            )
+        )
+    }
+
     fn is_catch_expr(&mut self) -> bool {
         self.token.is_keyword(keywords::Do) &&
         self.look_ahead(1, |t| t.is_keyword(keywords::Catch)) &&
@@ -4700,7 +4776,7 @@ fn parse_block_tail(&mut self, lo: Span, s: BlockCheckMode) -> PResult<'a, P<Blo
                 if macro_legacy_warnings && self.token != token::Semi {
                     self.warn_missing_semicolon();
                 } else {
-                    self.expect_one_of(&[token::Semi], &[])?;
+                    self.expect_one_of(&[], &[token::Semi])?;
                 }
             }
             _ => {}
@@ -4724,12 +4800,14 @@ fn warn_missing_semicolon(&self) {
 
     fn err_dotdotdot_syntax(&self, span: Span) {
         self.diagnostic().struct_span_err(span, {
-            "`...` syntax cannot be used in expressions"
-        }).help({
-            "Use `..` if you need an exclusive range (a < b)"
-        }).help({
-            "or `..=` if you need an inclusive range (a <= b)"
-        }).emit();
+            "unexpected token: `...`"
+        }).span_suggestion_with_applicability(
+            span, "use `..` for an exclusive range", "..".to_owned(),
+            Applicability::MaybeIncorrect
+        ).span_suggestion_with_applicability(
+            span, "or `..=` for an inclusive range", "..=".to_owned(),
+            Applicability::MaybeIncorrect
+        ).emit();
     }
 
     // Parse bounds of a type parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
@@ -4737,7 +4815,7 @@ fn err_dotdotdot_syntax(&self, span: Span) {
     // LT_BOUND = LIFETIME (e.g. `'a`)
     // TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
     // TY_BOUND_NOPAREN = [?] [for<LT_PARAM_DEFS>] SIMPLE_PATH (e.g. `?for<'a: 'b> m::Trait<'a>`)
-    fn parse_ty_param_bounds_common(&mut self, allow_plus: bool) -> PResult<'a, TyParamBounds> {
+    fn parse_generic_bounds_common(&mut self, allow_plus: bool) -> PResult<'a, GenericBounds> {
         let mut bounds = Vec::new();
         loop {
             // This needs to be syncronized with `Token::can_begin_bound`.
@@ -4754,7 +4832,7 @@ fn parse_ty_param_bounds_common(&mut self, allow_plus: bool) -> PResult<'a, TyPa
                         self.span_err(question_span,
                                       "`?` may only modify trait bounds, not lifetime bounds");
                     }
-                    bounds.push(RegionTyParamBound(self.expect_lifetime()));
+                    bounds.push(GenericBound::Outlives(self.expect_lifetime()));
                     if has_parens {
                         self.expect(&token::CloseDelim(token::Paren))?;
                         self.span_err(self.prev_span,
@@ -4772,7 +4850,7 @@ fn parse_ty_param_bounds_common(&mut self, allow_plus: bool) -> PResult<'a, TyPa
                     } else {
                         TraitBoundModifier::None
                     };
-                    bounds.push(TraitTyParamBound(poly_trait, modifier));
+                    bounds.push(GenericBound::Trait(poly_trait, modifier));
                 }
             } else {
                 break
@@ -4786,16 +4864,16 @@ fn parse_ty_param_bounds_common(&mut self, allow_plus: bool) -> PResult<'a, TyPa
         return Ok(bounds);
     }
 
-    fn parse_ty_param_bounds(&mut self) -> PResult<'a, TyParamBounds> {
-        self.parse_ty_param_bounds_common(true)
+    fn parse_generic_bounds(&mut self) -> PResult<'a, GenericBounds> {
+        self.parse_generic_bounds_common(true)
     }
 
     // Parse bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
     // BOUND = LT_BOUND (e.g. `'a`)
-    fn parse_lt_param_bounds(&mut self) -> Vec<Lifetime> {
+    fn parse_lt_param_bounds(&mut self) -> GenericBounds {
         let mut lifetimes = Vec::new();
         while self.check_lifetime() {
-            lifetimes.push(self.expect_lifetime());
+            lifetimes.push(ast::GenericBound::Outlives(self.expect_lifetime()));
 
             if !self.eat_plus() {
                 break
@@ -4805,12 +4883,14 @@ fn parse_lt_param_bounds(&mut self) -> Vec<Lifetime> {
     }
 
     /// Matches typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?
-    fn parse_ty_param(&mut self, preceding_attrs: Vec<Attribute>) -> PResult<'a, TyParam> {
+    fn parse_ty_param(&mut self,
+                      preceding_attrs: Vec<Attribute>)
+                      -> PResult<'a, GenericParam> {
         let ident = self.parse_ident()?;
 
         // Parse optional colon and param bounds.
         let bounds = if self.eat(&token::Colon) {
-            self.parse_ty_param_bounds()?
+            self.parse_generic_bounds()?
         } else {
             Vec::new()
         };
@@ -4821,25 +4901,27 @@ fn parse_ty_param(&mut self, preceding_attrs: Vec<Attribute>) -> PResult<'a, TyP
             None
         };
 
-        Ok(TyParam {
-            attrs: preceding_attrs.into(),
+        Ok(GenericParam {
             ident,
             id: ast::DUMMY_NODE_ID,
+            attrs: preceding_attrs.into(),
             bounds,
-            default,
+            kind: GenericParamKind::Type {
+                default,
+            }
         })
     }
 
     /// Parses the following grammar:
-    ///     TraitItemAssocTy = Ident ["<"...">"] [":" [TyParamBounds]] ["where" ...] ["=" Ty]
-    fn parse_trait_item_assoc_ty(&mut self, preceding_attrs: Vec<Attribute>)
-        -> PResult<'a, (ast::Generics, TyParam)> {
+    ///     TraitItemAssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
+    fn parse_trait_item_assoc_ty(&mut self)
+        -> PResult<'a, (Ident, TraitItemKind, ast::Generics)> {
         let ident = self.parse_ident()?;
         let mut generics = self.parse_generics()?;
 
         // Parse optional colon and param bounds.
         let bounds = if self.eat(&token::Colon) {
-            self.parse_ty_param_bounds()?
+            self.parse_generic_bounds()?
         } else {
             Vec::new()
         };
@@ -4852,13 +4934,7 @@ fn parse_trait_item_assoc_ty(&mut self, preceding_attrs: Vec<Attribute>)
         };
         self.expect(&token::Semi)?;
 
-        Ok((generics, TyParam {
-            attrs: preceding_attrs.into(),
-            ident,
-            id: ast::DUMMY_NODE_ID,
-            bounds,
-            default,
-        }))
+        Ok((ident, TraitItemKind::Type(bounds, default), generics))
     }
 
     /// Parses (possibly empty) list of lifetime and type parameters, possibly including
@@ -4876,18 +4952,20 @@ fn parse_trait_item_assoc_ty(&mut self, preceding_attrs: Vec<Attribute>)
                 } else {
                     Vec::new()
                 };
-                params.push(ast::GenericParam::Lifetime(LifetimeDef {
+                params.push(ast::GenericParam {
+                    ident: lifetime.ident,
+                    id: lifetime.id,
                     attrs: attrs.into(),
-                    lifetime,
                     bounds,
-                }));
+                    kind: ast::GenericParamKind::Lifetime,
+                });
                 if seen_ty_param {
                     self.span_err(self.prev_span,
                         "lifetime parameters must be declared prior to type parameters");
                 }
             } else if self.check_ident() {
                 // Parse type parameter.
-                params.push(ast::GenericParam::Type(self.parse_ty_param(attrs)?));
+                params.push(self.parse_ty_param(attrs)?);
                 seen_ty_param = true;
             } else {
                 // Check for trailing attributes and stop parsing.
@@ -4936,16 +5014,16 @@ fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
 
     /// Parses (possibly empty) list of lifetime and type arguments and associated type bindings,
     /// possibly including trailing comma.
-    fn parse_generic_args(&mut self) -> PResult<'a, (Vec<Lifetime>, Vec<P<Ty>>, Vec<TypeBinding>)> {
-        let mut lifetimes = Vec::new();
-        let mut types = Vec::new();
+    fn parse_generic_args(&mut self)
+                          -> PResult<'a, (Vec<GenericArg>, Vec<TypeBinding>)> {
+        let mut args = Vec::new();
         let mut bindings = Vec::new();
         let mut seen_type = false;
         let mut seen_binding = false;
         loop {
             if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
                 // Parse lifetime argument.
-                lifetimes.push(self.expect_lifetime());
+                args.push(GenericArg::Lifetime(self.expect_lifetime()));
                 if seen_type || seen_binding {
                     self.span_err(self.prev_span,
                         "lifetime parameters must be declared prior to type parameters");
@@ -4965,11 +5043,12 @@ fn parse_generic_args(&mut self) -> PResult<'a, (Vec<Lifetime>, Vec<P<Ty>>, Vec<
                 seen_binding = true;
             } else if self.check_type() {
                 // Parse type argument.
-                types.push(self.parse_ty()?);
+                let ty_param = self.parse_ty()?;
                 if seen_binding {
-                    self.span_err(types[types.len() - 1].span,
+                    self.span_err(ty_param.span,
                         "type parameters must be declared prior to associated type bindings");
                 }
+                args.push(GenericArg::Type(ty_param));
                 seen_type = true;
             } else {
                 break
@@ -4979,7 +5058,7 @@ fn parse_generic_args(&mut self) -> PResult<'a, (Vec<Lifetime>, Vec<P<Ty>>, Vec<
                 break
             }
         }
-        Ok((lifetimes, types, bindings))
+        Ok((args, bindings))
     }
 
     /// Parses an optional `where` clause and places it in `generics`.
@@ -5037,7 +5116,7 @@ fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> {
                 // or with mandatory equality sign and the second type.
                 let ty = self.parse_ty()?;
                 if self.eat(&token::Colon) {
-                    let bounds = self.parse_ty_param_bounds()?;
+                    let bounds = self.parse_generic_bounds()?;
                     where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
                         ast::WhereBoundPredicate {
                             span: lo.to(self.prev_span),
@@ -5339,6 +5418,7 @@ fn mk_item(&mut self, span: Span, ident: Ident, node: ItemKind, vis: Visibility,
     /// Parse an item-position function declaration.
     fn parse_item_fn(&mut self,
                      unsafety: Unsafety,
+                     asyncness: IsAsync,
                      constness: Spanned<Constness>,
                      abi: Abi)
                      -> PResult<'a, ItemInfo> {
@@ -5346,7 +5426,8 @@ fn parse_item_fn(&mut self,
         let decl = self.parse_fn_decl(false)?;
         generics.where_clause = self.parse_where_clause()?;
         let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
-        Ok((ident, ItemKind::Fn(decl, unsafety, constness, abi, generics, body), Some(inner_attrs)))
+        let header = FnHeader { unsafety, asyncness, constness, abi };
+        Ok((ident, ItemKind::Fn(decl, header, generics, body), Some(inner_attrs)))
     }
 
     /// true if we are looking at `const ID`, false for things like `const fn` etc
@@ -5364,10 +5445,18 @@ fn is_const_item(&mut self) -> bool {
     /// - `const unsafe fn`
     /// - `extern fn`
     /// - etc
-    fn parse_fn_front_matter(&mut self) -> PResult<'a, (Spanned<Constness>, Unsafety, Abi)> {
+    fn parse_fn_front_matter(&mut self)
+        -> PResult<'a, (
+            Spanned<Constness>,
+            Unsafety,
+            IsAsync,
+            Abi
+        )>
+    {
         let is_const_fn = self.eat_keyword(keywords::Const);
         let const_span = self.prev_span;
         let unsafety = self.parse_unsafety();
+        let asyncness = self.parse_asyncness();
         let (constness, unsafety, abi) = if is_const_fn {
             (respan(const_span, Constness::Const), unsafety, Abi::Rust)
         } else {
@@ -5379,11 +5468,11 @@ fn parse_fn_front_matter(&mut self) -> PResult<'a, (Spanned<Constness>, Unsafety
             (respan(self.prev_span, Constness::NotConst), unsafety, abi)
         };
         self.expect_keyword(keywords::Fn)?;
-        Ok((constness, unsafety, abi))
+        Ok((constness, unsafety, asyncness, abi))
     }
 
     /// Parse an impl item.
-    crate fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, ImplItem> {
+    pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, ImplItem> {
         maybe_whole!(self, NtImplItem, |x| x);
         let attrs = self.parse_outer_attributes()?;
         let (mut item, tokens) = self.collect_tokens(|this| {
@@ -5514,19 +5603,18 @@ fn parse_impl_method(&mut self, vis: &Visibility, at_end: &mut bool)
             Ok((keywords::Invalid.ident(), vec![], ast::Generics::default(),
                 ast::ImplItemKind::Macro(mac)))
         } else {
-            let (constness, unsafety, abi) = self.parse_fn_front_matter()?;
+            let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
             let ident = self.parse_ident()?;
             let mut generics = self.parse_generics()?;
             let decl = self.parse_fn_decl_with_self(|p| p.parse_arg())?;
             generics.where_clause = self.parse_where_clause()?;
             *at_end = true;
             let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
-            Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(ast::MethodSig {
-                abi,
-                unsafety,
-                constness,
-                decl,
-             }, body)))
+            let header = ast::FnHeader { abi, unsafety, constness, asyncness };
+            Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(
+                ast::MethodSig { header, decl },
+                body
+            )))
         }
     }
 
@@ -5537,14 +5625,14 @@ fn parse_item_trait(&mut self, is_auto: IsAuto, unsafety: Unsafety) -> PResult<'
 
         // Parse optional colon and supertrait bounds.
         let bounds = if self.eat(&token::Colon) {
-            self.parse_ty_param_bounds()?
+            self.parse_generic_bounds()?
         } else {
             Vec::new()
         };
 
         if self.eat(&token::Eq) {
             // it's a trait alias
-            let bounds = self.parse_ty_param_bounds()?;
+            let bounds = self.parse_generic_bounds()?;
             tps.where_clause = self.parse_where_clause()?;
             self.expect(&token::Semi)?;
             if unsafety != Unsafety::Normal {
@@ -5986,12 +6074,13 @@ pub fn parse_visibility(&mut self, can_take_tuple: bool) -> PResult<'a, Visibili
 `pub(super)`: visible only in the current module's parent
 `pub(in path::to::module)`: visible only on the specified path"##;
                 let path = self.parse_path(PathStyle::Mod)?;
-                let path_span = self.prev_span;
+                let sp = self.prev_span;
                 let help_msg = format!("make this visible only to module `{}` with `in`", path);
                 self.expect(&token::CloseDelim(token::Paren))?;  // `)`
-                let mut err = self.span_fatal_help(path_span, msg, suggestion);
+                let mut err = struct_span_err!(self.sess.span_diagnostic, sp, E0704, "{}", msg);
+                err.help(suggestion);
                 err.span_suggestion_with_applicability(
-                    path_span, &help_msg, format!("in {}", path), Applicability::MachineApplicable
+                    sp, &help_msg, format!("in {}", path), Applicability::MachineApplicable
                 );
                 err.emit();  // emit diagnostic, but continue with public visibility
             }
@@ -6535,12 +6624,15 @@ fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> {
                     Some(abi) => Ok(Some(abi)),
                     None => {
                         let prev_span = self.prev_span;
-                        self.span_err(
+                        let mut err = struct_span_err!(
+                            self.sess.span_diagnostic,
                             prev_span,
-                            &format!("invalid ABI: expected one of [{}], \
-                                     found `{}`",
-                                    abi::all_names().join(", "),
-                                    s));
+                            E0703,
+                            "invalid ABI: found `{}`",
+                            s);
+                        err.span_label(prev_span, "invalid ABI");
+                        err.help(&format!("valid ABIs: {}", abi::all_names().join(", ")));
+                        err.emit();
                         Ok(None)
                     }
                 }
@@ -6608,6 +6700,7 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
                 let abi = opt_abi.unwrap_or(Abi::C);
                 let (ident, item_, extra_attrs) =
                     self.parse_item_fn(Unsafety::Normal,
+                                       IsAsync::NotAsync,
                                        respan(fn_span, Constness::NotConst),
                                        abi)?;
                 let prev_span = self.prev_span;
@@ -6651,6 +6744,7 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
                 self.bump();
                 let (ident, item_, extra_attrs) =
                     self.parse_item_fn(unsafety,
+                                       IsAsync::NotAsync,
                                        respan(const_span, Constness::Const),
                                        Abi::Rust)?;
                 let prev_span = self.prev_span;
@@ -6678,6 +6772,34 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
                                     maybe_append(attrs, extra_attrs));
             return Ok(Some(item));
         }
+
+        // `unsafe async fn` or `async fn`
+        if (
+            self.check_keyword(keywords::Unsafe) &&
+            self.look_ahead(1, |t| t.is_keyword(keywords::Async))
+        ) || (
+            self.check_keyword(keywords::Async) &&
+            self.look_ahead(1, |t| t.is_keyword(keywords::Fn))
+        )
+        {
+            // ASYNC FUNCTION ITEM
+            let unsafety = self.parse_unsafety();
+            self.expect_keyword(keywords::Async)?;
+            self.expect_keyword(keywords::Fn)?;
+            let fn_span = self.prev_span;
+            let (ident, item_, extra_attrs) =
+                self.parse_item_fn(unsafety,
+                                   IsAsync::Async(ast::DUMMY_NODE_ID),
+                                   respan(fn_span, Constness::NotConst),
+                                   Abi::Rust)?;
+            let prev_span = self.prev_span;
+            let item = self.mk_item(lo.to(prev_span),
+                                    ident,
+                                    item_,
+                                    visibility,
+                                    maybe_append(attrs, extra_attrs));
+            return Ok(Some(item));
+        }
         if self.check_keyword(keywords::Unsafe) &&
             (self.look_ahead(1, |t| t.is_keyword(keywords::Trait)) ||
             self.look_ahead(1, |t| t.is_keyword(keywords::Auto)))
@@ -6723,6 +6845,7 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
             let fn_span = self.prev_span;
             let (ident, item_, extra_attrs) =
                 self.parse_item_fn(Unsafety::Normal,
+                                   IsAsync::NotAsync,
                                    respan(fn_span, Constness::NotConst),
                                    Abi::Rust)?;
             let prev_span = self.prev_span;
@@ -6748,6 +6871,7 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
             let fn_span = self.prev_span;
             let (ident, item_, extra_attrs) =
                 self.parse_item_fn(Unsafety::Unsafe,
+                                   IsAsync::NotAsync,
                                    respan(fn_span, Constness::NotConst),
                                    abi)?;
             let prev_span = self.prev_span;
@@ -7212,7 +7336,7 @@ pub fn parse_crate_mod(&mut self) -> PResult<'a, Crate> {
         })
     }
 
-    fn parse_optional_str(&mut self) -> Option<(Symbol, ast::StrStyle, Option<ast::Name>)> {
+    pub fn parse_optional_str(&mut self) -> Option<(Symbol, ast::StrStyle, Option<ast::Name>)> {
         let ret = match self.token {
             token::Literal(token::Str_(s), suf) => (s, ast::StrStyle::Cooked, suf),
             token::Literal(token::StrRaw(s, n), suf) => (s, ast::StrStyle::Raw(n), suf),
index 87edfd69e2bd6fda7480f904b6ac68826f337cba..70c4324a056a0ff62028a7bddf1dcc234b81a1d6 100644 (file)
 
 use rustc_target::spec::abi::{self, Abi};
 use ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
-use ast::{SelfKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
-use ast::{Attribute, MacDelimiter};
+use ast::{SelfKind, GenericBound, TraitBoundModifier};
+use ast::{Attribute, MacDelimiter, GenericArg};
 use util::parser::{self, AssocOp, Fixity};
 use attr;
 use codemap::{self, CodeMap};
 use syntax_pos::{self, BytePos};
-use syntax_pos::hygiene::{Mark, MarkKind, SyntaxContext};
+use syntax_pos::hygiene::{Mark, SyntaxContext};
 use parse::token::{self, BinOpToken, Token};
 use parse::lexer::comments;
 use parse::{self, ParseSess};
@@ -292,8 +292,8 @@ pub fn ty_to_string(ty: &ast::Ty) -> String {
     to_string(|s| s.print_type(ty))
 }
 
-pub fn bounds_to_string(bounds: &[ast::TyParamBound]) -> String {
-    to_string(|s| s.print_bounds("", bounds))
+pub fn bounds_to_string(bounds: &[ast::GenericBound]) -> String {
+    to_string(|s| s.print_type_bounds("", bounds))
 }
 
 pub fn pat_to_string(pat: &ast::Pat) -> String {
@@ -308,8 +308,8 @@ pub fn expr_to_string(e: &ast::Expr) -> String {
     to_string(|s| s.print_expr(e))
 }
 
-pub fn lifetime_to_string(e: &ast::Lifetime) -> String {
-    to_string(|s| s.print_lifetime(e))
+pub fn lifetime_to_string(lt: &ast::Lifetime) -> String {
+    to_string(|s| s.print_lifetime(*lt))
 }
 
 pub fn tt_to_string(tt: tokenstream::TokenTree) -> String {
@@ -373,14 +373,13 @@ pub fn vis_to_string(v: &ast::Visibility) -> String {
 }
 
 pub fn fun_to_string(decl: &ast::FnDecl,
-                     unsafety: ast::Unsafety,
-                     constness: ast::Constness,
+                     header: ast::FnHeader,
                      name: ast::Ident,
                      generics: &ast::Generics)
                      -> String {
     to_string(|s| {
         s.head("")?;
-        s.print_fn(decl, unsafety, constness, Abi::Rust, Some(name),
+        s.print_fn(decl, header, Some(name),
                    generics, &codemap::dummy_spanned(ast::VisibilityKind::Inherited))?;
         s.end()?; // Close the head box
         s.end() // Close the outer box
@@ -843,7 +842,7 @@ fn nbsp(&mut self) -> io::Result<()> { self.writer().word(" ") }
     fn print_dollar_crate(&mut self, mut ctxt: SyntaxContext) -> io::Result<()> {
         if let Some(mark) = ctxt.adjust(Mark::root()) {
             // Make a best effort to print something that complies
-            if mark.kind() == MarkKind::Builtin {
+            if mark.is_builtin() {
                 if let Some(name) = std_inject::injected_crate_name() {
                     self.writer().word("::")?;
                     self.writer().word(name)?;
@@ -1008,15 +1007,21 @@ pub fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod,
         Ok(())
     }
 
-    pub fn print_opt_lifetime(&mut self,
-                              lifetime: &Option<ast::Lifetime>) -> io::Result<()> {
-        if let Some(l) = *lifetime {
-            self.print_lifetime(&l)?;
+    pub fn print_opt_lifetime(&mut self, lifetime: &Option<ast::Lifetime>) -> io::Result<()> {
+        if let Some(lt) = *lifetime {
+            self.print_lifetime(lt)?;
             self.nbsp()?;
         }
         Ok(())
     }
 
+    pub fn print_generic_arg(&mut self, generic_arg: &GenericArg) -> io::Result<()> {
+        match generic_arg {
+            GenericArg::Lifetime(lt) => self.print_lifetime(*lt),
+            GenericArg::Type(ty) => self.print_type(ty),
+        }
+    }
+
     pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> {
         self.maybe_print_comment(ty.span.lo())?;
         self.ibox(0)?;
@@ -1071,10 +1076,10 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> {
             }
             ast::TyKind::TraitObject(ref bounds, syntax) => {
                 let prefix = if syntax == ast::TraitObjectSyntax::Dyn { "dyn" } else { "" };
-                self.print_bounds(prefix, &bounds[..])?;
+                self.print_type_bounds(prefix, &bounds[..])?;
             }
             ast::TyKind::ImplTrait(ref bounds) => {
-                self.print_bounds("impl", &bounds[..])?;
+                self.print_type_bounds("impl", &bounds[..])?;
             }
             ast::TyKind::Array(ref ty, ref length) => {
                 self.s.word("[")?;
@@ -1112,9 +1117,8 @@ pub fn print_foreign_item(&mut self,
         match item.node {
             ast::ForeignItemKind::Fn(ref decl, ref generics) => {
                 self.head("")?;
-                self.print_fn(decl, ast::Unsafety::Normal,
-                              ast::Constness::NotConst,
-                              Abi::Rust, Some(item.ident),
+                self.print_fn(decl, ast::FnHeader::default(),
+                              Some(item.ident),
                               generics, &item.vis)?;
                 self.end()?; // end head-ibox
                 self.s.word(";")?;
@@ -1171,13 +1175,13 @@ fn print_associated_const(&mut self,
 
     fn print_associated_type(&mut self,
                              ident: ast::Ident,
-                             bounds: Option<&ast::TyParamBounds>,
+                             bounds: Option<&ast::GenericBounds>,
                              ty: Option<&ast::Ty>)
                              -> io::Result<()> {
         self.word_space("type")?;
         self.print_ident(ident)?;
         if let Some(bounds) = bounds {
-            self.print_bounds(":", bounds)?;
+            self.print_type_bounds(":", bounds)?;
         }
         if let Some(ty) = ty {
             self.s.space()?;
@@ -1243,13 +1247,11 @@ pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
                 self.s.word(";")?;
                 self.end()?; // end the outer cbox
             }
-            ast::ItemKind::Fn(ref decl, unsafety, constness, abi, ref typarams, ref body) => {
+            ast::ItemKind::Fn(ref decl, header, ref typarams, ref body) => {
                 self.head("")?;
                 self.print_fn(
                     decl,
-                    unsafety,
-                    constness.node,
-                    abi,
+                    header,
                     Some(item.ident),
                     typarams,
                     &item.vis
@@ -1322,7 +1324,7 @@ pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
                 self.print_unsafety(unsafety)?;
                 self.word_nbsp("impl")?;
 
-                if generics.is_parameterized() {
+                if !generics.params.is_empty() {
                     self.print_generic_params(&generics.params)?;
                     self.s.space()?;
                 }
@@ -1358,7 +1360,7 @@ pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
                 self.print_generic_params(&generics.params)?;
                 let mut real_bounds = Vec::with_capacity(bounds.len());
                 for b in bounds.iter() {
-                    if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = *b {
+                    if let GenericBound::Trait(ref ptr, ast::TraitBoundModifier::Maybe) = *b {
                         self.s.space()?;
                         self.word_space("for ?")?;
                         self.print_trait_ref(&ptr.trait_ref)?;
@@ -1366,7 +1368,7 @@ pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
                         real_bounds.push(b.clone());
                     }
                 }
-                self.print_bounds(":", &real_bounds[..])?;
+                self.print_type_bounds(":", &real_bounds[..])?;
                 self.print_where_clause(&generics.where_clause)?;
                 self.s.word(" ")?;
                 self.bopen()?;
@@ -1384,7 +1386,7 @@ pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
                 let mut real_bounds = Vec::with_capacity(bounds.len());
                 // FIXME(durka) this seems to be some quite outdated syntax
                 for b in bounds.iter() {
-                    if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = *b {
+                    if let GenericBound::Trait(ref ptr, ast::TraitBoundModifier::Maybe) = *b {
                         self.s.space()?;
                         self.word_space("for ?")?;
                         self.print_trait_ref(&ptr.trait_ref)?;
@@ -1393,7 +1395,7 @@ pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
                     }
                 }
                 self.nbsp()?;
-                self.print_bounds("=", &real_bounds[..])?;
+                self.print_type_bounds("=", &real_bounds[..])?;
                 self.print_where_clause(&generics.where_clause)?;
                 self.s.word(";")?;
             }
@@ -1576,9 +1578,7 @@ pub fn print_method_sig(&mut self,
                             vis: &ast::Visibility)
                             -> io::Result<()> {
         self.print_fn(&m.decl,
-                      m.unsafety,
-                      m.constness.node,
-                      m.abi,
+                      m.header,
                       Some(ident),
                       &generics,
                       vis)
@@ -1984,8 +1984,8 @@ fn print_expr_method_call(&mut self,
         self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX)?;
         self.s.word(".")?;
         self.print_ident(segment.ident)?;
-        if let Some(ref parameters) = segment.parameters {
-            self.print_path_parameters(parameters, true)?;
+        if let Some(ref args) = segment.args {
+            self.print_generic_args(args, true)?;
         }
         self.print_call_post(base_args)
     }
@@ -2171,8 +2171,10 @@ fn print_expr_outer_attr_style(&mut self,
                 }
                 self.bclose_(expr.span, INDENT_UNIT)?;
             }
-            ast::ExprKind::Closure(capture_clause, movability, ref decl, ref body, _) => {
+            ast::ExprKind::Closure(
+                capture_clause, asyncness, movability, ref decl, ref body, _) => {
                 self.print_movability(movability)?;
+                self.print_asyncness(asyncness)?;
                 self.print_capture_clause(capture_clause)?;
 
                 self.print_fn_block_args(decl)?;
@@ -2196,6 +2198,12 @@ fn print_expr_outer_attr_style(&mut self,
                 self.ibox(0)?;
                 self.print_block_with_attrs(blk, attrs)?;
             }
+            ast::ExprKind::Async(capture_clause, _, ref blk) => {
+                self.word_nbsp("async")?;
+                self.print_capture_clause(capture_clause)?;
+                self.s.space()?;
+                self.print_block_with_attrs(blk, attrs)?;
+            }
             ast::ExprKind::Assign(ref lhs, ref rhs) => {
                 let prec = AssocOp::Assign.precedence() as i8;
                 self.print_expr_maybe_paren(lhs, prec + 1)?;
@@ -2428,8 +2436,8 @@ fn print_path_segment(&mut self,
         if segment.ident.name != keywords::CrateRoot.name() &&
            segment.ident.name != keywords::DollarCrate.name() {
             self.print_ident(segment.ident)?;
-            if let Some(ref parameters) = segment.parameters {
-                self.print_path_parameters(parameters, colons_before_params)?;
+            if let Some(ref args) = segment.args {
+                self.print_generic_args(args, colons_before_params)?;
             }
         } else if segment.ident.name == keywords::DollarCrate.name() {
             self.print_dollar_crate(segment.ident.span.ctxt())?;
@@ -2455,44 +2463,30 @@ fn print_qpath(&mut self,
         self.s.word("::")?;
         let item_segment = path.segments.last().unwrap();
         self.print_ident(item_segment.ident)?;
-        match item_segment.parameters {
-            Some(ref parameters) => self.print_path_parameters(parameters, colons_before_params),
+        match item_segment.args {
+            Some(ref args) => self.print_generic_args(args, colons_before_params),
             None => Ok(()),
         }
     }
 
-    fn print_path_parameters(&mut self,
-                             parameters: &ast::PathParameters,
-                             colons_before_params: bool)
-                             -> io::Result<()>
+    fn print_generic_args(&mut self,
+                          args: &ast::GenericArgs,
+                          colons_before_params: bool)
+                          -> io::Result<()>
     {
         if colons_before_params {
             self.s.word("::")?
         }
 
-        match *parameters {
-            ast::PathParameters::AngleBracketed(ref data) => {
+        match *args {
+            ast::GenericArgs::AngleBracketed(ref data) => {
                 self.s.word("<")?;
 
-                let mut comma = false;
-                for lifetime in &data.lifetimes {
-                    if comma {
-                        self.word_space(",")?
-                    }
-                    self.print_lifetime(lifetime)?;
-                    comma = true;
-                }
+                self.commasep(Inconsistent, &data.args, |s, generic_arg| {
+                    s.print_generic_arg(generic_arg)
+                })?;
 
-                if !data.types.is_empty() {
-                    if comma {
-                        self.word_space(",")?
-                    }
-                    self.commasep(
-                        Inconsistent,
-                        &data.types,
-                        |s, ty| s.print_type(ty))?;
-                        comma = true;
-                }
+                let mut comma = data.args.len() != 0;
 
                 for binding in data.bindings.iter() {
                     if comma {
@@ -2508,7 +2502,7 @@ fn print_path_parameters(&mut self,
                 self.s.word(">")?
             }
 
-            ast::PathParameters::Parenthesized(ref data) => {
+            ast::GenericArgs::Parenthesized(ref data) => {
                 self.s.word("(")?;
                 self.commasep(
                     Inconsistent,
@@ -2748,13 +2742,11 @@ fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) -> io::Resu
 
     pub fn print_fn(&mut self,
                     decl: &ast::FnDecl,
-                    unsafety: ast::Unsafety,
-                    constness: ast::Constness,
-                    abi: abi::Abi,
+                    header: ast::FnHeader,
                     name: Option<ast::Ident>,
                     generics: &ast::Generics,
                     vis: &ast::Visibility) -> io::Result<()> {
-        self.print_fn_header_info(unsafety, constness, abi, vis)?;
+        self.print_fn_header_info(header, vis)?;
 
         if let Some(name) = name {
             self.nbsp()?;
@@ -2808,6 +2800,14 @@ pub fn print_movability(&mut self, movability: ast::Movability)
         }
     }
 
+    pub fn print_asyncness(&mut self, asyncness: ast::IsAsync)
+                                -> io::Result<()> {
+        if asyncness.is_async() {
+            self.word_nbsp("async")?;
+        }
+        Ok(())
+    }
+
     pub fn print_capture_clause(&mut self, capture_clause: ast::CaptureBy)
                                 -> io::Result<()> {
         match capture_clause {
@@ -2816,9 +2816,9 @@ pub fn print_capture_clause(&mut self, capture_clause: ast::CaptureBy)
         }
     }
 
-    pub fn print_bounds(&mut self,
+    pub fn print_type_bounds(&mut self,
                         prefix: &str,
-                        bounds: &[ast::TyParamBound])
+                        bounds: &[ast::GenericBound])
                         -> io::Result<()> {
         if !bounds.is_empty() {
             self.s.word(prefix)?;
@@ -2834,32 +2834,25 @@ pub fn print_bounds(&mut self,
                 }
 
                 match bound {
-                    TraitTyParamBound(tref, modifier) => {
+                    GenericBound::Trait(tref, modifier) => {
                         if modifier == &TraitBoundModifier::Maybe {
                             self.s.word("?")?;
                         }
                         self.print_poly_trait_ref(tref)?;
                     }
-                    RegionTyParamBound(lt) => {
-                        self.print_lifetime(lt)?;
-                    }
+                    GenericBound::Outlives(lt) => self.print_lifetime(*lt)?,
                 }
             }
         }
         Ok(())
     }
 
-    pub fn print_lifetime(&mut self,
-                          lifetime: &ast::Lifetime)
-                          -> io::Result<()>
-    {
+    pub fn print_lifetime(&mut self, lifetime: ast::Lifetime) -> io::Result<()> {
         self.print_name(lifetime.ident.name)
     }
 
-    pub fn print_lifetime_bounds(&mut self,
-                                 lifetime: &ast::Lifetime,
-                                 bounds: &[ast::Lifetime])
-                                 -> io::Result<()>
+    pub fn print_lifetime_bounds(&mut self, lifetime: ast::Lifetime, bounds: &ast::GenericBounds)
+        -> io::Result<()>
     {
         self.print_lifetime(lifetime)?;
         if !bounds.is_empty() {
@@ -2868,7 +2861,10 @@ pub fn print_lifetime_bounds(&mut self,
                 if i != 0 {
                     self.s.word(" + ")?;
                 }
-                self.print_lifetime(bound)?;
+                match bound {
+                    ast::GenericBound::Outlives(lt) => self.print_lifetime(*lt)?,
+                    _ => panic!(),
+                }
             }
         }
         Ok(())
@@ -2885,12 +2881,25 @@ pub fn print_generic_params(
         self.s.word("<")?;
 
         self.commasep(Inconsistent, &generic_params, |s, param| {
-            match *param {
-                ast::GenericParam::Lifetime(ref lifetime_def) => {
-                    s.print_outer_attributes_inline(&lifetime_def.attrs)?;
-                    s.print_lifetime_bounds(&lifetime_def.lifetime, &lifetime_def.bounds)
+            match param.kind {
+                ast::GenericParamKind::Lifetime => {
+                    s.print_outer_attributes_inline(&param.attrs)?;
+                    let lt = ast::Lifetime { id: param.id, ident: param.ident };
+                    s.print_lifetime_bounds(lt, &param.bounds)
                 },
-                ast::GenericParam::Type(ref ty_param) => s.print_ty_param(ty_param),
+                ast::GenericParamKind::Type { ref default } => {
+                    s.print_outer_attributes_inline(&param.attrs)?;
+                    s.print_ident(param.ident)?;
+                    s.print_type_bounds(":", &param.bounds)?;
+                    match default {
+                        Some(ref default) => {
+                            s.s.space()?;
+                            s.word_space("=")?;
+                            s.print_type(default)
+                        }
+                        _ => Ok(())
+                    }
+                }
             }
         })?;
 
@@ -2898,20 +2907,6 @@ pub fn print_generic_params(
         Ok(())
     }
 
-    pub fn print_ty_param(&mut self, param: &ast::TyParam) -> io::Result<()> {
-        self.print_outer_attributes_inline(&param.attrs)?;
-        self.print_ident(param.ident)?;
-        self.print_bounds(":", &param.bounds)?;
-        match param.default {
-            Some(ref default) => {
-                self.s.space()?;
-                self.word_space("=")?;
-                self.print_type(default)
-            }
-            _ => Ok(())
-        }
-    }
-
     pub fn print_where_clause(&mut self, where_clause: &ast::WhereClause)
                               -> io::Result<()> {
         if where_clause.predicates.is_empty() {
@@ -2935,12 +2930,12 @@ pub fn print_where_clause(&mut self, where_clause: &ast::WhereClause)
                 }) => {
                     self.print_formal_generic_params(bound_generic_params)?;
                     self.print_type(bounded_ty)?;
-                    self.print_bounds(":", bounds)?;
+                    self.print_type_bounds(":", bounds)?;
                 }
                 ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
                                                                                ref bounds,
                                                                                ..}) => {
-                    self.print_lifetime_bounds(lifetime, bounds)?;
+                    self.print_lifetime_bounds(*lifetime, bounds)?;
                 }
                 ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ref lhs_ty,
                                                                        ref rhs_ty,
@@ -3071,9 +3066,7 @@ pub fn print_ty_fn(&mut self,
             span: syntax_pos::DUMMY_SP,
         };
         self.print_fn(decl,
-                      unsafety,
-                      ast::Constness::NotConst,
-                      abi,
+                      ast::FnHeader { unsafety, abi, ..ast::FnHeader::default() },
                       name,
                       &generics,
                       &codemap::dummy_spanned(ast::VisibilityKind::Inherited))?;
@@ -3136,22 +3129,21 @@ pub fn print_extern_opt_abi(&mut self,
     }
 
     pub fn print_fn_header_info(&mut self,
-                                unsafety: ast::Unsafety,
-                                constness: ast::Constness,
-                                abi: Abi,
+                                header: ast::FnHeader,
                                 vis: &ast::Visibility) -> io::Result<()> {
         self.s.word(&visibility_qualified(vis, ""))?;
 
-        match constness {
+        match header.constness.node {
             ast::Constness::NotConst => {}
             ast::Constness::Const => self.word_nbsp("const")?
         }
 
-        self.print_unsafety(unsafety)?;
+        self.print_asyncness(header.asyncness)?;
+        self.print_unsafety(header.unsafety)?;
 
-        if abi != Abi::Rust {
+        if header.abi != Abi::Rust {
             self.word_nbsp("extern")?;
-            self.word_nbsp(&abi.to_string())?;
+            self.word_nbsp(&header.abi.to_string())?;
         }
 
         self.s.word("fn")
@@ -3194,10 +3186,20 @@ fn test_fun_to_string() {
                 variadic: false
             };
             let generics = ast::Generics::default();
-            assert_eq!(fun_to_string(&decl, ast::Unsafety::Normal,
-                                    ast::Constness::NotConst,
-                                    abba_ident, &generics),
-                    "fn abba()");
+            assert_eq!(
+                fun_to_string(
+                    &decl,
+                    ast::FnHeader {
+                        unsafety: ast::Unsafety::Normal,
+                        constness: codemap::dummy_spanned(ast::Constness::NotConst),
+                        asyncness: ast::IsAsync::NotAsync,
+                        abi: Abi::Rust,
+                    },
+                    abba_ident,
+                    &generics
+                ),
+                "fn abba()"
+            );
         })
     }
 
index e9cd7adb9c166fa25f955bdf81ba11c7d3519f70..66e8e0d7a9c6c76e52dcaa0b0b850d62cce71ba9 100644 (file)
@@ -14,7 +14,7 @@
 use ext::hygiene::{Mark, SyntaxContext};
 use symbol::{Symbol, keywords};
 use syntax_pos::{DUMMY_SP, Span};
-use codemap::{ExpnInfo, NameAndSpan, MacroAttribute, dummy_spanned, hygiene, respan};
+use codemap::{ExpnInfo, MacroAttribute, dummy_spanned, hygiene, respan};
 use ptr::P;
 use tokenstream::TokenStream;
 
@@ -25,13 +25,11 @@ fn ignored_span(sp: Span) -> Span {
     let mark = Mark::fresh(Mark::root());
     mark.set_expn_info(ExpnInfo {
         call_site: DUMMY_SP,
-        callee: NameAndSpan {
-            format: MacroAttribute(Symbol::intern("std_inject")),
-            span: None,
-            allow_internal_unstable: true,
-            allow_internal_unsafe: false,
-            edition: hygiene::default_edition(),
-        }
+        def_site: None,
+        format: MacroAttribute(Symbol::intern("std_inject")),
+        allow_internal_unstable: true,
+        allow_internal_unsafe: false,
+        edition: hygiene::default_edition(),
     });
     sp.with_ctxt(SyntaxContext::empty().apply_mark(mark))
 }
index da7deb3c4cfe7856df02dbb981c61d663dc79b2a..141fd122ff57b6647cea156804d3da4b15322f8b 100644 (file)
@@ -22,7 +22,7 @@
 use attr::{self, HasAttrs};
 use syntax_pos::{self, DUMMY_SP, NO_EXPANSION, Span, FileMap, BytePos};
 
-use codemap::{self, CodeMap, ExpnInfo, NameAndSpan, MacroAttribute, dummy_spanned};
+use codemap::{self, CodeMap, ExpnInfo, MacroAttribute, dummy_spanned};
 use errors;
 use config;
 use entry::{self, EntryPointType};
@@ -124,24 +124,36 @@ fn fold_item(&mut self, i: P<ast::Item>) -> SmallVector<P<ast::Item>> {
 
         if is_test_fn(&self.cx, &i) || is_bench_fn(&self.cx, &i) {
             match i.node {
-                ast::ItemKind::Fn(_, ast::Unsafety::Unsafe, _, _, _, _) => {
-                    let diag = self.cx.span_diagnostic;
-                    diag.span_fatal(i.span, "unsafe functions cannot be used for tests").raise();
-                }
-                _ => {
-                    debug!("this is a test function");
-                    let test = Test {
-                        span: i.span,
-                        path: self.cx.path.clone(),
-                        bench: is_bench_fn(&self.cx, &i),
-                        ignore: is_ignored(&i),
-                        should_panic: should_panic(&i, &self.cx),
-                        allow_fail: is_allowed_fail(&i),
-                    };
-                    self.cx.testfns.push(test);
-                    self.tests.push(i.ident);
+                ast::ItemKind::Fn(_, header, _, _) => {
+                    if header.unsafety == ast::Unsafety::Unsafe {
+                        let diag = self.cx.span_diagnostic;
+                        diag.span_fatal(
+                            i.span,
+                            "unsafe functions cannot be used for tests"
+                        ).raise();
+                    }
+                    if header.asyncness.is_async() {
+                        let diag = self.cx.span_diagnostic;
+                        diag.span_fatal(
+                            i.span,
+                            "async functions cannot be used for tests"
+                        ).raise();
+                    }
                 }
+                _ => {},
             }
+
+            debug!("this is a test function");
+            let test = Test {
+                span: i.span,
+                path: self.cx.path.clone(),
+                bench: is_bench_fn(&self.cx, &i),
+                ignore: is_ignored(&i),
+                should_panic: should_panic(&i, &self.cx),
+                allow_fail: is_allowed_fail(&i),
+            };
+            self.cx.testfns.push(test);
+            self.tests.push(i.ident);
         }
 
         let mut item = i.into_inner();
@@ -295,13 +307,11 @@ fn generate_test_harness(sess: &ParseSess,
 
     mark.set_expn_info(ExpnInfo {
         call_site: DUMMY_SP,
-        callee: NameAndSpan {
-            format: MacroAttribute(Symbol::intern("test")),
-            span: None,
-            allow_internal_unstable: true,
-            allow_internal_unsafe: false,
-            edition: hygiene::default_edition(),
-        }
+        def_site: None,
+        format: MacroAttribute(Symbol::intern("test")),
+        allow_internal_unstable: true,
+        allow_internal_unsafe: false,
+        edition: hygiene::default_edition(),
     });
 
     TestHarnessGenerator {
@@ -338,7 +348,7 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
     fn has_test_signature(_cx: &TestCtxt, i: &ast::Item) -> HasTestSignature {
         let has_should_panic_attr = attr::contains_name(&i.attrs, "should_panic");
         match i.node {
-            ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => {
+            ast::ItemKind::Fn(ref decl, _, ref generics, _) => {
                 // If the termination trait is active, the compiler will check that the output
                 // type implements the `Termination` trait as `libtest` enforces that.
                 let has_output = match decl.output {
@@ -353,7 +363,7 @@ fn has_test_signature(_cx: &TestCtxt, i: &ast::Item) -> HasTestSignature {
 
                 match (has_output, has_should_panic_attr) {
                     (true, true) => No(BadTestSignature::ShouldPanicOnlyWithNoArgs),
-                    (true, false) => if generics.is_parameterized() {
+                    (true, false) => if !generics.params.is_empty() {
                         No(BadTestSignature::WrongTypeSignature)
                     } else {
                         Yes
@@ -396,7 +406,7 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
 
     fn has_bench_signature(_cx: &TestCtxt, i: &ast::Item) -> bool {
         match i.node {
-            ast::ItemKind::Fn(ref decl, _, _, _, _, _) => {
+            ast::ItemKind::Fn(ref decl, _, _, _) => {
                 // NB: inadequate check, but we're running
                 // well before resolve, can't get too deep.
                 decl.inputs.len() == 1
@@ -537,9 +547,7 @@ fn mk_main(cx: &mut TestCtxt) -> P<ast::Item> {
     let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(vec![]));
     let main_body = ecx.block(sp, vec![call_test_main]);
     let main = ast::ItemKind::Fn(ecx.fn_decl(vec![], ast::FunctionRetTy::Ty(main_ret_ty)),
-                           ast::Unsafety::Normal,
-                           dummy_spanned(ast::Constness::NotConst),
-                           ::rustc_target::spec::abi::Abi::Rust,
+                           ast::FnHeader::default(),
                            ast::Generics::default(),
                            main_body);
     P(ast::Item {
index d4c6b4b158b25dc2590063e1e04d6e0cced892c7..ebb3081c1fde5586665e08271e5cdd35ef972e75 100644 (file)
@@ -95,9 +95,9 @@ fn visit_trait_ref(&mut self, t: &TraitRef) {
         self.count += 1;
         walk_trait_ref(self, t)
     }
-    fn visit_ty_param_bound(&mut self, bounds: &TyParamBound) {
+    fn visit_param_bound(&mut self, bounds: &GenericBound) {
         self.count += 1;
-        walk_ty_param_bound(self, bounds)
+        walk_param_bound(self, bounds)
     }
     fn visit_poly_trait_ref(&mut self, t: &PolyTraitRef, m: &TraitBoundModifier) {
         self.count += 1;
@@ -137,9 +137,9 @@ fn visit_use_tree(&mut self, use_tree: &UseTree, id: NodeId, _nested: bool) {
         self.count += 1;
         walk_use_tree(self, use_tree, id)
     }
-    fn visit_path_parameters(&mut self, path_span: Span, path_parameters: &PathParameters) {
+    fn visit_generic_args(&mut self, path_span: Span, generic_args: &GenericArgs) {
         self.count += 1;
-        walk_path_parameters(self, path_span, path_parameters)
+        walk_generic_args(self, path_span, generic_args)
     }
     fn visit_assoc_type_binding(&mut self, type_binding: &TypeBinding) {
         self.count += 1;
index 51b535275d649e7c73b96af0d66087040e493c66..15d910b33b064c9a3a37ca59b70421d965b0c930 100644 (file)
@@ -277,6 +277,7 @@ pub enum ExprPrecedence {
     Block,
     Catch,
     Struct,
+    Async,
 }
 
 impl PartialOrd for ExprPrecedence {
@@ -346,6 +347,7 @@ pub fn order(self) -> i8 {
             ExprPrecedence::Match |
             ExprPrecedence::Block |
             ExprPrecedence::Catch |
+            ExprPrecedence::Async |
             ExprPrecedence::Struct => PREC_PAREN,
         }
     }
index adda39c62ed0e2b4c3b9c6be026c84c9bd7ff7ce..41e3ad9d4f4b1c944d9e122b83f508c2c91b86e2 100644 (file)
 //! instance, a walker looking for item names in a module will miss all of
 //! those that are created by the expansion of a macro.
 
-use rustc_target::spec::abi::Abi;
 use ast::*;
 use syntax_pos::Span;
-use codemap::Spanned;
 use parse::token::Token;
 use tokenstream::{TokenTree, TokenStream};
 
 #[derive(Copy, Clone, PartialEq, Eq)]
 pub enum FnKind<'a> {
     /// fn foo() or extern "Abi" fn foo()
-    ItemFn(Ident, Unsafety, Spanned<Constness>, Abi, &'a Visibility, &'a Block),
+    ItemFn(Ident, FnHeader, &'a Visibility, &'a Block),
 
     /// fn foo(&self)
     Method(Ident, &'a MethodSig, Option<&'a Visibility>, &'a Block),
@@ -73,7 +71,9 @@ fn visit_anon_const(&mut self, c: &'ast AnonConst) { walk_anon_const(self, c) }
     fn visit_expr(&mut self, ex: &'ast Expr) { walk_expr(self, ex) }
     fn visit_expr_post(&mut self, _ex: &'ast Expr) { }
     fn visit_ty(&mut self, t: &'ast Ty) { walk_ty(self, t) }
-    fn visit_generic_param(&mut self, param: &'ast GenericParam) { walk_generic_param(self, param) }
+    fn visit_generic_param(&mut self, param: &'ast GenericParam) {
+        walk_generic_param(self, param)
+    }
     fn visit_generics(&mut self, g: &'ast Generics) { walk_generics(self, g) }
     fn visit_where_predicate(&mut self, p: &'ast WherePredicate) {
         walk_where_predicate(self, p)
@@ -84,8 +84,8 @@ fn visit_fn(&mut self, fk: FnKind<'ast>, fd: &'ast FnDecl, s: Span, _: NodeId) {
     fn visit_trait_item(&mut self, ti: &'ast TraitItem) { walk_trait_item(self, ti) }
     fn visit_impl_item(&mut self, ii: &'ast ImplItem) { walk_impl_item(self, ii) }
     fn visit_trait_ref(&mut self, t: &'ast TraitRef) { walk_trait_ref(self, t) }
-    fn visit_ty_param_bound(&mut self, bounds: &'ast TyParamBound) {
-        walk_ty_param_bound(self, bounds)
+    fn visit_param_bound(&mut self, bounds: &'ast GenericBound) {
+        walk_param_bound(self, bounds)
     }
     fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef, m: &'ast TraitBoundModifier) {
         walk_poly_trait_ref(self, t, m)
@@ -128,8 +128,14 @@ fn visit_use_tree(&mut self, use_tree: &'ast UseTree, id: NodeId, _nested: bool)
     fn visit_path_segment(&mut self, path_span: Span, path_segment: &'ast PathSegment) {
         walk_path_segment(self, path_span, path_segment)
     }
-    fn visit_path_parameters(&mut self, path_span: Span, path_parameters: &'ast PathParameters) {
-        walk_path_parameters(self, path_span, path_parameters)
+    fn visit_generic_args(&mut self, path_span: Span, generic_args: &'ast GenericArgs) {
+        walk_generic_args(self, path_span, generic_args)
+    }
+    fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) {
+        match generic_arg {
+            GenericArg::Lifetime(lt) => self.visit_lifetime(lt),
+            GenericArg::Type(ty) => self.visit_ty(ty),
+        }
     }
     fn visit_assoc_type_binding(&mut self, type_binding: &'ast TypeBinding) {
         walk_assoc_type_binding(self, type_binding)
@@ -227,10 +233,10 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
             visitor.visit_ty(typ);
             visitor.visit_expr(expr);
         }
-        ItemKind::Fn(ref declaration, unsafety, constness, abi, ref generics, ref body) => {
+        ItemKind::Fn(ref declaration, header, ref generics, ref body) => {
             visitor.visit_generics(generics);
-            visitor.visit_fn(FnKind::ItemFn(item.ident, unsafety,
-                                            constness, abi, &item.vis, body),
+            visitor.visit_fn(FnKind::ItemFn(item.ident, header,
+                                            &item.vis, body),
                              declaration,
                              item.span,
                              item.id)
@@ -268,12 +274,12 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
         }
         ItemKind::Trait(.., ref generics, ref bounds, ref methods) => {
             visitor.visit_generics(generics);
-            walk_list!(visitor, visit_ty_param_bound, bounds);
+            walk_list!(visitor, visit_param_bound, bounds);
             walk_list!(visitor, visit_trait_item, methods);
         }
         ItemKind::TraitAlias(ref generics, ref bounds) => {
             visitor.visit_generics(generics);
-            walk_list!(visitor, visit_ty_param_bound, bounds);
+            walk_list!(visitor, visit_param_bound, bounds);
         }
         ItemKind::Mac(ref mac) => visitor.visit_mac(mac),
         ItemKind::MacroDef(ref ts) => visitor.visit_mac_def(ts, item.id),
@@ -333,7 +339,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
         }
         TyKind::TraitObject(ref bounds, ..) |
         TyKind::ImplTrait(ref bounds) => {
-            walk_list!(visitor, visit_ty_param_bound, bounds);
+            walk_list!(visitor, visit_param_bound, bounds);
         }
         TyKind::Typeof(ref expression) => {
             visitor.visit_anon_const(expression)
@@ -375,23 +381,22 @@ pub fn walk_path_segment<'a, V: Visitor<'a>>(visitor: &mut V,
                                              path_span: Span,
                                              segment: &'a PathSegment) {
     visitor.visit_ident(segment.ident);
-    if let Some(ref parameters) = segment.parameters {
-        visitor.visit_path_parameters(path_span, parameters);
+    if let Some(ref args) = segment.args {
+        visitor.visit_generic_args(path_span, args);
     }
 }
 
-pub fn walk_path_parameters<'a, V>(visitor: &mut V,
-                                   _path_span: Span,
-                                   path_parameters: &'a PathParameters)
+pub fn walk_generic_args<'a, V>(visitor: &mut V,
+                                _path_span: Span,
+                                generic_args: &'a GenericArgs)
     where V: Visitor<'a>,
 {
-    match *path_parameters {
-        PathParameters::AngleBracketed(ref data) => {
-            walk_list!(visitor, visit_ty, &data.types);
-            walk_list!(visitor, visit_lifetime, &data.lifetimes);
+    match *generic_args {
+        GenericArgs::AngleBracketed(ref data) => {
+            walk_list!(visitor, visit_generic_arg, &data.args);
             walk_list!(visitor, visit_assoc_type_binding, &data.bindings);
         }
-        PathParameters::Parenthesized(ref data) => {
+        GenericArgs::Parenthesized(ref data) => {
             walk_list!(visitor, visit_ty, &data.inputs);
             walk_list!(visitor, visit_ty, &data.output);
         }
@@ -472,30 +477,20 @@ pub fn walk_global_asm<'a, V: Visitor<'a>>(_: &mut V, _: &'a GlobalAsm) {
     // Empty!
 }
 
-pub fn walk_ty_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a TyParamBound) {
+pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) {
     match *bound {
-        TraitTyParamBound(ref typ, ref modifier) => {
-            visitor.visit_poly_trait_ref(typ, modifier);
-        }
-        RegionTyParamBound(ref lifetime) => {
-            visitor.visit_lifetime(lifetime);
-        }
+        GenericBound::Trait(ref typ, ref modifier) => visitor.visit_poly_trait_ref(typ, modifier),
+        GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
     }
 }
 
 pub fn walk_generic_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a GenericParam) {
-    match *param {
-        GenericParam::Lifetime(ref l) => {
-            visitor.visit_ident(l.lifetime.ident);
-            walk_list!(visitor, visit_lifetime, &l.bounds);
-            walk_list!(visitor, visit_attribute, &*l.attrs);
-        }
-        GenericParam::Type(ref t) => {
-            visitor.visit_ident(t.ident);
-            walk_list!(visitor, visit_ty_param_bound, &t.bounds);
-            walk_list!(visitor, visit_ty, &t.default);
-            walk_list!(visitor, visit_attribute, &*t.attrs);
-        }
+    visitor.visit_ident(param.ident);
+    walk_list!(visitor, visit_attribute, param.attrs.iter());
+    walk_list!(visitor, visit_param_bound, &param.bounds);
+    match param.kind {
+        GenericParamKind::Lifetime => {}
+        GenericParamKind::Type { ref default } => walk_list!(visitor, visit_ty, default),
     }
 }
 
@@ -511,14 +506,14 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(visitor: &mut V, predicate: &'a
                                                            ref bound_generic_params,
                                                            ..}) => {
             visitor.visit_ty(bounded_ty);
-            walk_list!(visitor, visit_ty_param_bound, bounds);
+            walk_list!(visitor, visit_param_bound, bounds);
             walk_list!(visitor, visit_generic_param, bound_generic_params);
         }
         WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime,
                                                              ref bounds,
                                                              ..}) => {
             visitor.visit_lifetime(lifetime);
-            walk_list!(visitor, visit_lifetime, bounds);
+            walk_list!(visitor, visit_param_bound, bounds);
         }
         WherePredicate::EqPredicate(WhereEqPredicate{ref lhs_ty,
                                                      ref rhs_ty,
@@ -547,7 +542,7 @@ pub fn walk_fn<'a, V>(visitor: &mut V, kind: FnKind<'a>, declaration: &'a FnDecl
     where V: Visitor<'a>,
 {
     match kind {
-        FnKind::ItemFn(_, _, _, _, _, body) => {
+        FnKind::ItemFn(_, _, _, body) => {
             walk_fn_decl(visitor, declaration);
             visitor.visit_block(body);
         }
@@ -579,7 +574,7 @@ pub fn walk_trait_item<'a, V: Visitor<'a>>(visitor: &mut V, trait_item: &'a Trai
                              &sig.decl, trait_item.span, trait_item.id);
         }
         TraitItemKind::Type(ref bounds, ref default) => {
-            walk_list!(visitor, visit_ty_param_bound, bounds);
+            walk_list!(visitor, visit_param_bound, bounds);
             walk_list!(visitor, visit_ty, default);
         }
         TraitItemKind::Macro(ref mac) => {
@@ -740,7 +735,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
             visitor.visit_expr(subexpression);
             walk_list!(visitor, visit_arm, arms);
         }
-        ExprKind::Closure(_, _, ref function_declaration, ref body, _decl_span) => {
+        ExprKind::Closure(_, _, _, ref function_declaration, ref body, _decl_span) => {
             visitor.visit_fn(FnKind::Closure(body),
                              function_declaration,
                              expression.span,
@@ -750,6 +745,9 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
             walk_list!(visitor, visit_label, opt_label);
             visitor.visit_block(block);
         }
+        ExprKind::Async(_, _, ref body) => {
+            visitor.visit_block(body);
+        }
         ExprKind::Assign(ref left_hand_expression, ref right_hand_expression) => {
             visitor.visit_expr(left_hand_expression);
             visitor.visit_expr(right_hand_expression);
index dec24d13c9b493fd766013b773c612a14f966f0a..9aeac5b1ddb2ae9937cb952897cde1b90e4cda49 100644 (file)
@@ -13,6 +13,7 @@
 use deriving::generic::ty::*;
 
 use syntax::ast::{self, Expr, Generics, ItemKind, MetaItem, VariantData};
+use syntax::ast::GenericArg;
 use syntax::attr;
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
@@ -48,7 +49,10 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
                 ItemKind::Struct(_, Generics { ref params, .. }) |
                 ItemKind::Enum(_, Generics { ref params, .. }) => {
                     if attr::contains_name(&annitem.attrs, "rustc_copy_clone_marker") &&
-                        !params.iter().any(|param| param.is_type_param())
+                        !params.iter().any(|param| match param.kind {
+                            ast::GenericParamKind::Type { .. } => true,
+                            _ => false,
+                        })
                     {
                         bounds = vec![];
                         is_shallow = true;
@@ -123,7 +127,7 @@ fn assert_ty_bounds(cx: &mut ExtCtxt, stmts: &mut Vec<ast::Stmt>,
         let span = span.with_ctxt(cx.backtrace());
         let assert_path = cx.path_all(span, true,
                                         cx.std_path(&["clone", helper_name]),
-                                        vec![], vec![ty], vec![]);
+                                        vec![GenericArg::Type(ty)], vec![]);
         stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path)));
     }
     fn process_variant(cx: &mut ExtCtxt, stmts: &mut Vec<ast::Stmt>, variant: &VariantData) {
index 237c8654edf6ea127ca5873be4afba2b6ba6243d..00ab39032acbd2489dbdc6273ca1812d1a8f9259 100644 (file)
@@ -12,7 +12,7 @@
 use deriving::generic::*;
 use deriving::generic::ty::*;
 
-use syntax::ast::{self, Expr, MetaItem};
+use syntax::ast::{self, Expr, MetaItem, GenericArg};
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
@@ -62,7 +62,7 @@ fn assert_ty_bounds(cx: &mut ExtCtxt, stmts: &mut Vec<ast::Stmt>,
         let span = span.with_ctxt(cx.backtrace());
         let assert_path = cx.path_all(span, true,
                                         cx.std_path(&["cmp", helper_name]),
-                                        vec![], vec![ty], vec![]);
+                                        vec![GenericArg::Type(ty)], vec![]);
         stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path)));
     }
     fn process_variant(cx: &mut ExtCtxt, stmts: &mut Vec<ast::Stmt>, variant: &ast::VariantData) {
index 80f65957c39a2e3935c41ef99b961c2c083e50bd..3ea0eb8bbd842e63155a3c1369b9116a540892fa 100644 (file)
 use std::vec;
 
 use rustc_target::spec::abi::Abi;
-use syntax::ast::{
-    self, BinOpKind, EnumDef, Expr, GenericParam, Generics, Ident, PatKind, VariantData
-};
-
+use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
+use syntax::ast::{VariantData, GenericParamKind, GenericArg};
 use syntax::attr;
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
-use syntax::codemap::{self, dummy_spanned, respan};
+use syntax::codemap::{self, respan};
 use syntax::util::move_map::MoveMap;
 use syntax::ptr::P;
 use syntax::symbol::{Symbol, keywords};
@@ -424,7 +422,10 @@ pub fn expand_ext(self,
                     ast::ItemKind::Struct(_, ref generics) |
                     ast::ItemKind::Enum(_, ref generics) |
                     ast::ItemKind::Union(_, ref generics) => {
-                        !generics.params.iter().any(|p| p.is_type_param())
+                        !generics.params.iter().any(|param| match param.kind {
+                            ast::GenericParamKind::Type { .. } => true,
+                            _ => false,
+                        })
                     }
                     _ => {
                         // Non-ADT derive is an error, but it should have been
@@ -548,30 +549,27 @@ fn create_derived_impl(&self,
             .to_generics(cx, self.span, type_ident, generics);
 
         // Create the generic parameters
-        params.extend(generics.params.iter().map(|param| {
-            match *param {
-                ref l @ GenericParam::Lifetime(_) => l.clone(),
-                GenericParam::Type(ref ty_param) => {
-                    // I don't think this can be moved out of the loop, since
-                    // a TyParamBound requires an ast id
-                    let mut bounds: Vec<_> =
-                        // extra restrictions on the generics parameters to the
-                        // type being derived upon
-                        self.additional_bounds.iter().map(|p| {
-                            cx.typarambound(p.to_path(cx, self.span,
-                                                        type_ident, generics))
-                        }).collect();
-
-                    // require the current trait
-                    bounds.push(cx.typarambound(trait_path.clone()));
-
-                    // also add in any bounds from the declaration
-                    for declared_bound in ty_param.bounds.iter() {
-                        bounds.push((*declared_bound).clone());
-                    }
-
-                    GenericParam::Type(cx.typaram(self.span, ty_param.ident, vec![], bounds, None))
+        params.extend(generics.params.iter().map(|param| match param.kind {
+            GenericParamKind::Lifetime { .. } => param.clone(),
+            GenericParamKind::Type { .. } => {
+                // I don't think this can be moved out of the loop, since
+                // a GenericBound requires an ast id
+                let mut bounds: Vec<_> =
+                    // extra restrictions on the generics parameters to the
+                    // type being derived upon
+                    self.additional_bounds.iter().map(|p| {
+                        cx.trait_bound(p.to_path(cx, self.span, type_ident, generics))
+                    }).collect();
+
+                // require the current trait
+                bounds.push(cx.trait_bound(trait_path.clone()));
+
+                // also add in any bounds from the declaration
+                for declared_bound in &param.bounds {
+                    bounds.push((*declared_bound).clone());
                 }
+
+                cx.typaram(self.span, param.ident, vec![], bounds, None)
             }
         }));
 
@@ -608,8 +606,8 @@ fn create_derived_impl(&self,
             // Extra scope required here so ty_params goes out of scope before params is moved
 
             let mut ty_params = params.iter()
-                .filter_map(|param| match *param {
-                    ast::GenericParam::Type(ref t) => Some(t),
+                .filter_map(|param| match param.kind {
+                    ast::GenericParamKind::Type { .. } => Some(param),
                     _ => None,
                 })
                 .peekable();
@@ -636,12 +634,12 @@ fn create_derived_impl(&self,
                         let mut bounds: Vec<_> = self.additional_bounds
                             .iter()
                             .map(|p| {
-                                cx.typarambound(p.to_path(cx, self.span, type_ident, generics))
+                                cx.trait_bound(p.to_path(cx, self.span, type_ident, generics))
                             })
                             .collect();
 
                         // require the current trait
-                        bounds.push(cx.typarambound(trait_path.clone()));
+                        bounds.push(cx.trait_bound(trait_path.clone()));
 
                         let predicate = ast::WhereBoundPredicate {
                             span: self.span,
@@ -666,31 +664,18 @@ fn create_derived_impl(&self,
         // Create the reference to the trait.
         let trait_ref = cx.trait_ref(trait_path);
 
-        // Create the type parameters on the `self` path.
-        let self_ty_params = generics.params
-            .iter()
-            .filter_map(|param| match *param {
-                GenericParam::Type(ref ty_param)
-                    => Some(cx.ty_ident(self.span, ty_param.ident)),
-                _ => None,
-            })
-            .collect();
-
-        let self_lifetimes: Vec<ast::Lifetime> = generics.params
-            .iter()
-            .filter_map(|param| match *param {
-                GenericParam::Lifetime(ref ld) => Some(ld.lifetime),
-                _ => None,
-            })
-            .collect();
+        let self_params: Vec<_> = generics.params.iter().map(|param| match param.kind {
+            GenericParamKind::Lifetime { .. } => {
+                GenericArg::Lifetime(cx.lifetime(self.span, param.ident))
+            }
+            GenericParamKind::Type { .. } => {
+                GenericArg::Type(cx.ty_ident(self.span, param.ident))
+            }
+        }).collect();
 
         // Create the type of `self`.
-        let self_type = cx.ty_path(cx.path_all(self.span,
-                                               false,
-                                               vec![type_ident],
-                                               self_lifetimes,
-                                               self_ty_params,
-                                               Vec::new()));
+        let path = cx.path_all(self.span, false, vec![type_ident], self_params, vec![]);
+        let self_type = cx.ty_path(path);
 
         let attr = cx.attribute(self.span,
                                 cx.meta_word(self.span,
@@ -986,10 +971,10 @@ fn create_method(&self,
             defaultness: ast::Defaultness::Final,
             ident: method_ident,
             node: ast::ImplItemKind::Method(ast::MethodSig {
-                                                abi,
-                                                unsafety,
-                                                constness:
-                                                    dummy_spanned(ast::Constness::NotConst),
+                                                header: ast::FnHeader {
+                                                    unsafety, abi,
+                                                    ..ast::FnHeader::default()
+                                                },
                                                 decl: fn_decl,
                                             },
                                             body_block),
index 25a2969448835dca4ba648e9be841b01dd61ee0f..0b809ab585cdcb9cd2e927e74640049e8bf4f94a 100644 (file)
@@ -15,7 +15,7 @@
 pub use self::Ty::*;
 
 use syntax::ast;
-use syntax::ast::{Expr, GenericParam, Generics, Ident, SelfKind};
+use syntax::ast::{Expr, GenericParamKind, Generics, Ident, SelfKind, GenericArg};
 use syntax::ext::base::ExtCtxt;
 use syntax::ext::build::AstBuilder;
 use syntax::codemap::{respan, DUMMY_SP};
@@ -86,15 +86,20 @@ pub fn to_path(&self,
                    -> ast::Path {
         let mut idents = self.path.iter().map(|s| cx.ident_of(*s)).collect();
         let lt = mk_lifetimes(cx, span, &self.lifetime);
-        let tys = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
+        let tys: Vec<P<ast::Ty>> =
+            self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
+        let params = lt.into_iter()
+                       .map(|lt| GenericArg::Lifetime(lt))
+                       .chain(tys.into_iter().map(|ty| GenericArg::Type(ty)))
+                       .collect();
 
         match self.kind {
-            PathKind::Global => cx.path_all(span, true, idents, lt, tys, Vec::new()),
-            PathKind::Local => cx.path_all(span, false, idents, lt, tys, Vec::new()),
+            PathKind::Global => cx.path_all(span, true, idents, params, Vec::new()),
+            PathKind::Local => cx.path_all(span, false, idents, params, Vec::new()),
             PathKind::Std => {
                 let def_site = DUMMY_SP.apply_mark(cx.current_expansion.mark);
                 idents.insert(0, Ident::new(keywords::DollarCrate.name(), def_site));
-                cx.path_all(span, false, idents, lt, tys, Vec::new())
+                cx.path_all(span, false, idents, params, Vec::new())
             }
         }
 
@@ -180,34 +185,22 @@ pub fn to_path(&self,
                    cx: &ExtCtxt,
                    span: Span,
                    self_ty: Ident,
-                   self_generics: &Generics)
+                   generics: &Generics)
                    -> ast::Path {
         match *self {
             Self_ => {
-                let self_params = self_generics.params
-                    .iter()
-                    .filter_map(|param| match *param {
-                        GenericParam::Type(ref ty_param) => Some(cx.ty_ident(span, ty_param.ident)),
-                        _ => None,
-                    })
-                    .collect();
-
-                let lifetimes: Vec<ast::Lifetime> = self_generics.params
-                    .iter()
-                    .filter_map(|param| match *param {
-                        GenericParam::Lifetime(ref ld) => Some(ld.lifetime),
-                        _ => None,
-                    })
-                    .collect();
+                let params: Vec<_> = generics.params.iter().map(|param| match param.kind {
+                    GenericParamKind::Lifetime { .. } => {
+                        GenericArg::Lifetime(ast::Lifetime { id: param.id, ident: param.ident })
+                    }
+                    GenericParamKind::Type { .. } => {
+                        GenericArg::Type(cx.ty_ident(span, param.ident))
+                    }
+                }).collect();
 
-                cx.path_all(span,
-                            false,
-                            vec![self_ty],
-                            lifetimes,
-                            self_params,
-                            Vec::new())
+                cx.path_all(span, false, vec![self_ty], params, vec![])
             }
-            Literal(ref p) => p.to_path(cx, span, self_ty, self_generics),
+            Literal(ref p) => p.to_path(cx, span, self_ty, generics),
             Ptr(..) => cx.span_bug(span, "pointer in a path in generic `derive`"),
             Tuple(..) => cx.span_bug(span, "tuple in a path in generic `derive`"),
         }
@@ -222,17 +215,17 @@ fn mk_ty_param(cx: &ExtCtxt,
                bounds: &[Path],
                self_ident: Ident,
                self_generics: &Generics)
-               -> ast::TyParam {
+               -> ast::GenericParam {
     let bounds = bounds.iter()
         .map(|b| {
             let path = b.to_path(cx, span, self_ident, self_generics);
-            cx.typarambound(path)
+            cx.trait_bound(path)
         })
         .collect();
     cx.typaram(span, cx.ident_of(name), attrs.to_owned(), bounds, None)
 }
 
-fn mk_generics(params: Vec<GenericParam>, span: Span) -> Generics {
+fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics {
     Generics {
         params,
         where_clause: ast::WhereClause {
@@ -268,17 +261,14 @@ pub fn to_generics(&self,
             .iter()
             .map(|&(lt, ref bounds)| {
                 let bounds = bounds.iter()
-                    .map(|b| cx.lifetime(span, Ident::from_str(b)))
-                    .collect();
-                GenericParam::Lifetime(cx.lifetime_def(span, Ident::from_str(lt), vec![], bounds))
+                    .map(|b| ast::GenericBound::Outlives(cx.lifetime(span, Ident::from_str(b))));
+                cx.lifetime_def(span, Ident::from_str(lt), vec![], bounds.collect())
             })
             .chain(self.bounds
                 .iter()
                 .map(|t| {
                     let (name, ref bounds) = *t;
-                    GenericParam::Type(mk_ty_param(
-                        cx, span, name, &[], &bounds, self_ty, self_generics
-                    ))
+                    mk_ty_param(cx, span, name, &[], &bounds, self_ty, self_generics)
                 })
             )
             .collect();
index a5b348a661a78a5ed78e2f7f24022a945d79753a..e6a1434ca9d10ca540432f668a1008ed6be7da3f 100644 (file)
@@ -134,9 +134,12 @@ fn hygienic_type_parameter(item: &Annotatable, base: &str) -> String {
         match item.node {
             ast::ItemKind::Struct(_, ast::Generics { ref params, .. }) |
             ast::ItemKind::Enum(_, ast::Generics { ref params, .. }) => {
-                for param in params.iter() {
-                    if let ast::GenericParam::Type(ref ty) = *param{
-                        typaram.push_str(&ty.ident.as_str());
+                for param in params {
+                    match param.kind {
+                        ast::GenericParamKind::Type { .. } => {
+                            typaram.push_str(&param.ident.as_str());
+                        }
+                        _ => {}
                     }
                 }
             }
@@ -154,11 +157,11 @@ fn call_intrinsic(cx: &ExtCtxt,
                   intrinsic: &str,
                   args: Vec<P<ast::Expr>>)
                   -> P<ast::Expr> {
-    if cx.current_expansion.mark.expn_info().unwrap().callee.allow_internal_unstable {
+    if cx.current_expansion.mark.expn_info().unwrap().allow_internal_unstable {
         span = span.with_ctxt(cx.backtrace());
     } 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;
+        info.allow_internal_unstable = true;
         let mark = Mark::fresh(Mark::root());
         mark.set_expn_info(info);
         span = span.with_ctxt(SyntaxContext::empty().apply_mark(mark));
index 4e1af108ab4fa038765d01da23b0977a3d5922ce..bbc5b03d6885eaa3f1a69cf2119b7d12f3550827 100644 (file)
@@ -13,7 +13,7 @@
 // interface.
 //
 
-use syntax::ast::{self, Ident};
+use syntax::ast::{self, Ident, GenericArg};
 use syntax::ext::base::*;
 use syntax::ext::base;
 use syntax::ext::build::AstBuilder;
@@ -39,12 +39,11 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt,
             cx.expr_path(cx.path_all(sp,
                                      true,
                                      cx.std_path(&["option", "Option", "None"]),
-                                     Vec::new(),
-                                     vec![cx.ty_rptr(sp,
+                                     vec![GenericArg::Type(cx.ty_rptr(sp,
                                                      cx.ty_ident(sp, Ident::from_str("str")),
                                                      Some(lt),
-                                                     ast::Mutability::Immutable)],
-                                     Vec::new()))
+                                                     ast::Mutability::Immutable))],
+                                     vec![]))
         }
         Ok(s) => {
             cx.expr_call_global(sp,
index 3593165023a54611cde685e540ce2039e87e267f..ee343e47bd8905c5d44c4ce6bee4bdc892df6879 100644 (file)
@@ -14,7 +14,7 @@
 
 use syntax::ast::{self, Ident, NodeId};
 use syntax::attr;
-use syntax::codemap::{ExpnInfo, NameAndSpan, MacroAttribute, hygiene, respan};
+use syntax::codemap::{ExpnInfo, MacroAttribute, hygiene, respan};
 use syntax::ext::base::ExtCtxt;
 use syntax::ext::build::AstBuilder;
 use syntax::ext::expand::ExpansionConfig;
@@ -364,13 +364,11 @@ fn mk_registrar(cx: &mut ExtCtxt,
     let mark = Mark::fresh(Mark::root());
     mark.set_expn_info(ExpnInfo {
         call_site: DUMMY_SP,
-        callee: NameAndSpan {
-            format: MacroAttribute(Symbol::intern("proc_macro")),
-            span: None,
-            allow_internal_unstable: true,
-            allow_internal_unsafe: false,
-            edition: hygiene::default_edition(),
-        }
+        def_site: None,
+        format: MacroAttribute(Symbol::intern("proc_macro")),
+        allow_internal_unstable: true,
+        allow_internal_unsafe: false,
+        edition: hygiene::default_edition(),
     });
     let span = DUMMY_SP.apply_mark(mark);
 
index 6dd910fba8218ab482e8a789d9a9ab8e93bfafc8..3365d5954033fd6ea73e95461eff85ab9f93d793 100644 (file)
@@ -29,7 +29,7 @@
 #[derive(Clone, Copy, PartialEq, Eq, Default, PartialOrd, Ord, Hash)]
 pub struct SyntaxContext(pub(super) u32);
 
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
 pub struct SyntaxContextData {
     pub outer_mark: Mark,
     pub prev_ctxt: SyntaxContext,
@@ -40,23 +40,44 @@ pub struct SyntaxContextData {
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub struct Mark(u32);
 
+#[derive(Debug)]
 struct MarkData {
     parent: Mark,
-    kind: MarkKind,
+    transparency: Transparency,
+    is_builtin: bool,
     expn_info: Option<ExpnInfo>,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq)]
-pub enum MarkKind {
-    Modern,
-    Builtin,
-    Legacy,
+/// A property of a macro expansion that determines how identifiers
+/// produced by that expansion are resolved.
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub enum Transparency {
+    /// Identifier produced by a transparent expansion is always resolved at call-site.
+    /// Call-site spans in procedural macros, hygiene opt-out in `macro` should use this.
+    /// (Not used yet.)
+    Transparent,
+    /// Identifier produced by a semi-transparent expansion may be resolved
+    /// either at call-site or at definition-site.
+    /// If it's a local variable, label or `$crate` then it's resolved at def-site.
+    /// Otherwise it's resolved at call-site.
+    /// `macro_rules` macros behave like this, built-in macros currently behave like this too,
+    /// but that's an implementation detail.
+    SemiTransparent,
+    /// Identifier produced by an opaque expansion is always resolved at definition-site.
+    /// Def-site spans in procedural macros, identifiers from `macro` by default use this.
+    Opaque,
 }
 
 impl Mark {
     pub fn fresh(parent: Mark) -> Self {
         HygieneData::with(|data| {
-            data.marks.push(MarkData { parent: parent, kind: MarkKind::Legacy, expn_info: None });
+            data.marks.push(MarkData {
+                parent,
+                // By default expansions behave like `macro_rules`.
+                transparency: Transparency::SemiTransparent,
+                is_builtin: false,
+                expn_info: None,
+            });
             Mark(data.marks.len() as u32 - 1)
         })
     }
@@ -84,28 +105,45 @@ pub fn expn_info(self) -> Option<ExpnInfo> {
 
     #[inline]
     pub fn set_expn_info(self, info: ExpnInfo) {
-        HygieneData::with(|data| data.marks[self.0 as usize].expn_info = Some(info))
+        HygieneData::with(|data| {
+            let old_info = &mut data.marks[self.0 as usize].expn_info;
+            if let Some(old_info) = old_info {
+                panic!("expansion info is reset for the mark {}\nold: {:#?}\nnew: {:#?}",
+                       self.0, old_info, info);
+            }
+            *old_info = Some(info);
+        })
     }
 
     pub fn modern(mut self) -> Mark {
         HygieneData::with(|data| {
-            loop {
-                if self == Mark::root() || data.marks[self.0 as usize].kind == MarkKind::Modern {
-                    return self;
-                }
+            while data.marks[self.0 as usize].transparency != Transparency::Opaque {
                 self = data.marks[self.0 as usize].parent;
             }
+            self
         })
     }
 
     #[inline]
-    pub fn kind(self) -> MarkKind {
-        HygieneData::with(|data| data.marks[self.0 as usize].kind)
+    pub fn transparency(self) -> Transparency {
+        assert_ne!(self, Mark::root());
+        HygieneData::with(|data| data.marks[self.0 as usize].transparency)
     }
 
     #[inline]
-    pub fn set_kind(self, kind: MarkKind) {
-        HygieneData::with(|data| data.marks[self.0 as usize].kind = kind)
+    pub fn set_transparency(self, transparency: Transparency) {
+        assert_ne!(self, Mark::root());
+        HygieneData::with(|data| data.marks[self.0 as usize].transparency = transparency)
+    }
+
+    #[inline]
+    pub fn is_builtin(self) -> bool {
+        HygieneData::with(|data| data.marks[self.0 as usize].is_builtin)
+    }
+
+    #[inline]
+    pub fn set_is_builtin(self, is_builtin: bool) {
+        HygieneData::with(|data| data.marks[self.0 as usize].is_builtin = is_builtin)
     }
 
     pub fn is_descendant_of(mut self, ancestor: Mark) -> bool {
@@ -147,6 +185,7 @@ pub fn least_ancestor(mut a: Mark, mut b: Mark) -> Mark {
     }
 }
 
+#[derive(Debug)]
 pub struct HygieneData {
     marks: Vec<MarkData>,
     syntax_contexts: Vec<SyntaxContextData>,
@@ -160,7 +199,10 @@ pub fn new() -> Self {
         HygieneData {
             marks: vec![MarkData {
                 parent: Mark::root(),
-                kind: MarkKind::Builtin,
+                // If the root is opaque, then loops searching for an opaque mark
+                // will automatically stop after reaching it.
+                transparency: Transparency::Opaque,
+                is_builtin: true,
                 expn_info: None,
             }],
             syntax_contexts: vec![SyntaxContextData {
@@ -206,8 +248,9 @@ pub fn allocate_directly(expansion_info: ExpnInfo) -> Self {
         HygieneData::with(|data| {
             data.marks.push(MarkData {
                 parent: Mark::root(),
-                kind: MarkKind::Legacy,
-                expn_info: Some(expansion_info)
+                transparency: Transparency::SemiTransparent,
+                is_builtin: false,
+                expn_info: Some(expansion_info),
             });
 
             let mark = Mark(data.marks.len() as u32 - 1);
@@ -223,7 +266,7 @@ pub fn allocate_directly(expansion_info: ExpnInfo) -> Self {
 
     /// Extend a syntax context with a given mark
     pub fn apply_mark(self, mark: Mark) -> SyntaxContext {
-        if mark.kind() == MarkKind::Modern {
+        if mark.transparency() == Transparency::Opaque {
             return self.apply_mark_internal(mark);
         }
 
@@ -253,7 +296,7 @@ fn apply_mark_internal(self, mark: Mark) -> SyntaxContext {
         HygieneData::with(|data| {
             let syntax_contexts = &mut data.syntax_contexts;
             let mut modern = syntax_contexts[self.0 as usize].modern;
-            if data.marks[mark.0 as usize].kind == MarkKind::Modern {
+            if data.marks[mark.0 as usize].transparency == Transparency::Opaque {
                 modern = *data.markings.entry((modern, mark)).or_insert_with(|| {
                     let len = syntax_contexts.len() as u32;
                     syntax_contexts.push(SyntaxContextData {
@@ -439,12 +482,11 @@ pub struct ExpnInfo {
     /// call_site span would have its own ExpnInfo, with the call_site
     /// pointing to the `foo!` invocation.
     pub call_site: Span,
-    /// Information about the expansion.
-    pub callee: NameAndSpan
-}
-
-#[derive(Clone, Hash, Debug, RustcEncodable, RustcDecodable)]
-pub struct NameAndSpan {
+    /// The span of the macro definition itself. The macro may not
+    /// have a sensible definition span (e.g. something defined
+    /// completely inside libsyntax) in which case this is None.
+    /// This span serves only informational purpose and is not used for resolution.
+    pub def_site: Option<Span>,
     /// The format with which the macro was invoked.
     pub format: ExpnFormat,
     /// Whether the macro is allowed to use #[unstable]/feature-gated
@@ -456,20 +498,6 @@ pub struct NameAndSpan {
     pub allow_internal_unsafe: bool,
     /// Edition of the crate in which the macro is defined.
     pub edition: Edition,
-    /// The span of the macro definition itself. The macro may not
-    /// have a sensible definition span (e.g. something defined
-    /// completely inside libsyntax) in which case this is None.
-    pub span: Option<Span>
-}
-
-impl NameAndSpan {
-    pub fn name(&self) -> Symbol {
-        match self.format {
-            ExpnFormat::MacroAttribute(s) |
-            ExpnFormat::MacroBang(s) => s,
-            ExpnFormat::CompilerDesugaring(ref kind) => kind.as_symbol(),
-        }
-    }
 }
 
 /// The source of expansion.
@@ -483,8 +511,17 @@ pub enum ExpnFormat {
     CompilerDesugaring(CompilerDesugaringKind)
 }
 
+impl ExpnFormat {
+    pub fn name(&self) -> Symbol {
+        match *self {
+            ExpnFormat::MacroBang(name) | ExpnFormat::MacroAttribute(name) => name,
+            ExpnFormat::CompilerDesugaring(kind) => kind.name(),
+        }
+    }
+}
+
 /// The kind of compiler desugaring.
-#[derive(Clone, Hash, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, Hash, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub enum CompilerDesugaringKind {
     DotFill,
     QuestionMark,
@@ -493,18 +530,18 @@ pub enum CompilerDesugaringKind {
     /// to an `existential type Foo: Trait;` + replacing the
     /// `impl Trait` with `Foo`.
     ExistentialReturnType,
+    Async,
 }
 
 impl CompilerDesugaringKind {
-    pub fn as_symbol(&self) -> Symbol {
-        use CompilerDesugaringKind::*;
-        let s = match *self {
-            DotFill => "...",
-            QuestionMark => "?",
-            Catch => "do catch",
-            ExistentialReturnType => "existental type",
-        };
-        Symbol::intern(s)
+    pub fn name(self) -> Symbol {
+        Symbol::intern(match self {
+            CompilerDesugaringKind::Async => "async",
+            CompilerDesugaringKind::DotFill => "...",
+            CompilerDesugaringKind::QuestionMark => "?",
+            CompilerDesugaringKind::Catch => "do catch",
+            CompilerDesugaringKind::ExistentialReturnType => "existential type",
+        })
     }
 }
 
index 17163576901eb86bd21a8e30a75bd45954a83348..a4fb9571ecbe9a75e260e9c40be19a74ceb9815d 100644 (file)
@@ -51,7 +51,7 @@
 
 pub mod edition;
 pub mod hygiene;
-pub use hygiene::{Mark, SyntaxContext, ExpnInfo, ExpnFormat, NameAndSpan, CompilerDesugaringKind};
+pub use hygiene::{Mark, SyntaxContext, ExpnInfo, ExpnFormat, CompilerDesugaringKind};
 
 mod span_encoding;
 pub use span_encoding::{Span, DUMMY_SP};
@@ -303,19 +303,19 @@ pub fn parent(self) -> Option<Span> {
     /// Edition of the crate from which this span came.
     pub fn edition(self) -> edition::Edition {
         self.ctxt().outer().expn_info().map_or_else(|| hygiene::default_edition(),
-                                                    |einfo| einfo.callee.edition)
+                                                    |einfo| einfo.edition)
     }
 
     /// Return the source callee.
     ///
-    /// Returns None if the supplied span has no expansion trace,
-    /// else returns the NameAndSpan for the macro definition
+    /// Returns `None` if the supplied span has no expansion trace,
+    /// else returns the `ExpnInfo` for the macro definition
     /// corresponding to the source callsite.
-    pub fn source_callee(self) -> Option<NameAndSpan> {
-        fn source_callee(info: ExpnInfo) -> NameAndSpan {
+    pub fn source_callee(self) -> Option<ExpnInfo> {
+        fn source_callee(info: ExpnInfo) -> ExpnInfo {
             match info.call_site.ctxt().outer().expn_info() {
                 Some(info) => source_callee(info),
-                None => info.callee,
+                None => info,
             }
         }
         self.ctxt().outer().expn_info().map(source_callee)
@@ -326,7 +326,7 @@ fn source_callee(info: ExpnInfo) -> NameAndSpan {
     /// `#[allow_internal_unstable]`).
     pub fn allows_unstable(&self) -> bool {
         match self.ctxt().outer().expn_info() {
-            Some(info) => info.callee.allow_internal_unstable,
+            Some(info) => info.allow_internal_unstable,
             None => false,
         }
     }
@@ -334,7 +334,7 @@ pub fn allows_unstable(&self) -> bool {
     /// Check if this span arises from a compiler desugaring of kind `kind`.
     pub fn is_compiler_desugaring(&self, kind: CompilerDesugaringKind) -> bool {
         match self.ctxt().outer().expn_info() {
-            Some(info) => match info.callee.format {
+            Some(info) => match info.format {
                 ExpnFormat::CompilerDesugaring(k) => k == kind,
                 _ => false,
             },
@@ -346,7 +346,7 @@ pub fn is_compiler_desugaring(&self, kind: CompilerDesugaringKind) -> bool {
     /// if this span is not from a desugaring.
     pub fn compiler_desugaring_kind(&self) -> Option<CompilerDesugaringKind> {
         match self.ctxt().outer().expn_info() {
-            Some(info) => match info.callee.format {
+            Some(info) => match info.format {
                 ExpnFormat::CompilerDesugaring(k) => Some(k),
                 _ => None
             },
@@ -359,7 +359,7 @@ pub fn compiler_desugaring_kind(&self) -> Option<CompilerDesugaringKind> {
     //  (that is, a macro marked with `#[allow_internal_unsafe]`).
     pub fn allows_unsafe(&self) -> bool {
         match self.ctxt().outer().expn_info() {
-            Some(info) => info.callee.allow_internal_unsafe,
+            Some(info) => info.allow_internal_unsafe,
             None => false,
         }
     }
@@ -368,20 +368,17 @@ pub fn macro_backtrace(mut self) -> Vec<MacroBacktrace> {
         let mut prev_span = DUMMY_SP;
         let mut result = vec![];
         while let Some(info) = self.ctxt().outer().expn_info() {
-            let (pre, post) = match info.callee.format {
-                ExpnFormat::MacroAttribute(..) => ("#[", "]"),
-                ExpnFormat::MacroBang(..) => ("", "!"),
-                ExpnFormat::CompilerDesugaring(..) => ("desugaring of `", "`"),
-            };
-            let macro_decl_name = format!("{}{}{}", pre, info.callee.name(), post);
-            let def_site_span = info.callee.span;
-
             // Don't print recursive invocations
             if !info.call_site.source_equal(&prev_span) {
+                let (pre, post) = match info.format {
+                    ExpnFormat::MacroAttribute(..) => ("#[", "]"),
+                    ExpnFormat::MacroBang(..) => ("", "!"),
+                    ExpnFormat::CompilerDesugaring(..) => ("desugaring of `", "`"),
+                };
                 result.push(MacroBacktrace {
                     call_site: info.call_site,
-                    macro_decl_name,
-                    def_site_span,
+                    macro_decl_name: format!("{}{}{}", pre, info.format.name(), post),
+                    def_site_span: info.def_site,
                 });
             }
 
index f1827022964169293e55e73260846c06158fca5e..3bb0382ef037be8299c335d675a14253ca13d9b1 100644 (file)
@@ -14,7 +14,7 @@ trait Get {
 }
 
 fn foo<T:Get>(t: T) {
-    let x = t.get(); //~ ERROR `<T as Get>::Value: std::marker::Sized` is not
+    let x = t.get(); //~ ERROR the size for value values of type
 }
 
 fn main() {
index 5e3cb606ce0371f258c77d2ec1576f398f29addd..07e80b61cd0a69cc764a016b88c15c940a9efe3d 100644 (file)
@@ -7,6 +7,7 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
+
 #![crate_name="lint_stability"]
 #![crate_type = "lib"]
 #![feature(staged_api)]
@@ -20,6 +21,10 @@ pub fn deprecated() {}
 #[rustc_deprecated(since = "1.0.0", reason = "text")]
 pub fn deprecated_text() {}
 
+#[stable(feature = "test_feature", since = "1.0.0")]
+#[rustc_deprecated(since = "99.99.99", reason = "text")]
+pub fn deprecated_future() {}
+
 #[unstable(feature = "test_feature", issue = "0")]
 #[rustc_deprecated(since = "1.0.0", reason = "text")]
 pub fn deprecated_unstable() {}
index 5be90f05018331389eddcbee6a33e2a9dbfa9061..7cef3f13dfc2cef2c574a2916f839748471d0aa0 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 fn foo<T:'static>() {
-    1.bar::<T>(); //~ ERROR `T: std::marker::Send` is not satisfied
+    1.bar::<T>(); //~ ERROR `T` cannot be sent between threads safely
 }
 
 trait bar {
index df3da5096bf538d9d57639d729b92b178b0bbcb3..9b87ec4d446cd155bf5ce4f2a8b18317973b20fb 100644 (file)
@@ -13,6 +13,6 @@ trait Trait {}
 pub fn main() {
     let x: Vec<Trait + Sized> = Vec::new();
     //~^ ERROR only auto traits can be used as additional traits in a trait object
-    //~| ERROR the trait bound `Trait: std::marker::Sized` is not satisfied
-    //~| ERROR the trait bound `Trait: std::marker::Sized` is not satisfied
+    //~| ERROR the size for value values of type
+    //~| ERROR the size for value values of type
 }
index 261881d880bf9fcd8074f34c6d371cfa86046114..3f7f2adabdfb114d5dae43c5502319c942028642 100644 (file)
@@ -14,7 +14,7 @@
 trait Foo : Send+Sync { }
 
 impl <T: Sync+'static> Foo for (T,) { }
-//~^ ERROR the trait bound `T: std::marker::Send` is not satisfied in `(T,)` [E0277]
+//~^ ERROR `T` cannot be sent between threads safely [E0277]
 
 impl <T: Send> Foo for (T,T) { }
 //~^ ERROR `T` cannot be shared between threads safely [E0277]
index de2084c4e8187baa3d52ae9dc0323d8c128ba662..88b5a3fbb55b63337fbcd6cb14cacf4f8580f12d 100644 (file)
@@ -22,6 +22,6 @@
 impl <T:Sync> RequiresShare for X<T> { }
 
 impl <T:Sync+'static> RequiresRequiresShareAndSend for X<T> { }
-//~^ ERROR `T: std::marker::Send` is not satisfied
+//~^ ERROR `T` cannot be sent between threads safely [E0277]
 
 fn main() { }
index 6dc5f39cb30dfa05a8cc741781deed0fd0bffefe..22dc9598d29ca1d373d409a63d9a5c261434a53e 100644 (file)
@@ -14,6 +14,6 @@
 trait Foo : Send { }
 
 impl Foo for std::rc::Rc<i8> { }
-//~^ ERROR `std::rc::Rc<i8>: std::marker::Send` is not satisfied
+//~^ ERROR `std::rc::Rc<i8>` cannot be sent between threads safely
 
 fn main() { }
index d4bb8de13d056fc84ff13e5eb52853f66520524b..e0b2043c1107c80e6fdc81f7565cbdaa94455dac 100644 (file)
@@ -12,6 +12,7 @@
 
 trait Foo : Send { }
 
-impl <T: Sync+'static> Foo for T { } //~ ERROR `T: std::marker::Send` is not satisfied
+impl <T: Sync+'static> Foo for T { }
+//~^ ERROR `T` cannot be sent between threads safely
 
 fn main() { }
index b9224e7be7f12eddf404f034462e1ccabf2f7305..12e9fb30902b5a5dafc6a488393984ebee701f57 100644 (file)
@@ -13,7 +13,7 @@ struct X<F> where F: FnOnce() + 'static + Send {
 }
 
 fn foo<F>(blk: F) -> X<F> where F: FnOnce() + 'static {
-    //~^ ERROR `F: std::marker::Send` is not satisfied
+    //~^ ERROR `F` cannot be sent between threads safely
     return X { field: blk };
 }
 
index 847a82c082651f1a4550cc7bfc34aefa873f2fa3..7c76cf475d29afe415b27502c5451252a11eb354 100644 (file)
@@ -18,6 +18,6 @@ impl Trait for Foo {}
 pub fn main() {
     let x: Box<Trait> = Box::new(Foo);
     let _y: &Trait = x; //~ ERROR E0308
-                        //~| expected type `&Trait`
-                        //~| found type `std::boxed::Box<Trait>`
+                        //~| expected type `&dyn Trait`
+                        //~| found type `std::boxed::Box<dyn Trait>`
 }
index 09bd3a2fc57d97a4f02744a84621c97622f16baa..b5acdc12ca048679c0f8ebe259a77995c66e02a0 100644 (file)
@@ -33,23 +33,23 @@ fn main() {
     let &&x = &&(&1isize as &T);
 
     // n == m
-    let &x = &1isize as &T;      //~ ERROR type `&T` cannot be dereferenced
-    let &&x = &(&1isize as &T);  //~ ERROR type `&T` cannot be dereferenced
-    let box x = box 1isize as Box<T>; //~ ERROR type `std::boxed::Box<T>` cannot be dereferenced
+    let &x = &1isize as &T;      //~ ERROR type `&dyn T` cannot be dereferenced
+    let &&x = &(&1isize as &T);  //~ ERROR type `&dyn T` cannot be dereferenced
+    let box x = box 1isize as Box<T>; //~ ERROR type `std::boxed::Box<dyn T>` cannot be dereferenced
 
     // n > m
     let &&x = &1isize as &T;
     //~^ ERROR mismatched types
-    //~| expected type `T`
+    //~| expected type `dyn T`
     //~| found type `&_`
     //~| expected trait T, found reference
     let &&&x = &(&1isize as &T);
     //~^ ERROR mismatched types
-    //~| expected type `T`
+    //~| expected type `dyn T`
     //~| found type `&_`
     //~| expected trait T, found reference
     let box box x = box 1isize as Box<T>;
     //~^ ERROR mismatched types
-    //~| expected type `T`
+    //~| expected type `dyn T`
     //~| found type `std::boxed::Box<_>`
 }
index 10c8f1eed00b0dfe89e26e241c48f738d69db49d..1dbdd42ca36e267e8e32f9bdcefe0cc9f54b9431 100644 (file)
@@ -43,5 +43,6 @@ pub fn main() {
     let f5: &mut Fat<ToBar> = &mut Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} };
     let z: Box<ToBar> = Box::new(Bar1 {f: 36});
     f5.ptr = *z;
-    //~^ ERROR `ToBar: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
+
 }
index ceaa371623223647c6eed876b18004a785f465a1..2a209a2959bfd7bf08c84b4338d92a636de68c28 100644 (file)
@@ -42,8 +42,8 @@ pub fn main() {
     let z: Box<ToBar> = Box::new(Bar1 {f: 36});
     f5.2 = Bar1 {f: 36};
     //~^ ERROR mismatched types
-    //~| expected type `ToBar`
+    //~| expected type `dyn ToBar`
     //~| found type `Bar1`
     //~| expected trait ToBar, found struct `Bar1`
-    //~| ERROR `ToBar: std::marker::Sized` is not satisfied
+    //~| ERROR the size for value values of type
 }
index 4f7d07600ad154e68712ea96b736c627d8161d0c..e28586c4755e872320a026ee9b195ab5b623e1d6 100644 (file)
@@ -44,8 +44,8 @@ pub fn main() {
     let z: Box<ToBar> = Box::new(Bar1 {f: 36});
     f5.ptr = Bar1 {f: 36};
     //~^ ERROR mismatched types
-    //~| expected type `ToBar`
+    //~| expected type `dyn ToBar`
     //~| found type `Bar1`
     //~| expected trait ToBar, found struct `Bar1`
-    //~| ERROR `ToBar: std::marker::Sized` is not satisfied
+    //~| ERROR the size for value values of type
 }
index 0c812b1d815ab000da92254d3c9cf6d4affb9a6e..82d81913cd3a3dbd6a290bc52ccb72c742d61459 100644 (file)
@@ -19,5 +19,5 @@ pub fn main() {
     let f: ([isize; 3],) = ([5, 6, 7],);
     let g: &([isize],) = &f;
     let h: &(([isize],),) = &(*g,);
-    //~^ ERROR `[isize]: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
index f508364d75115fa74f7a10baab0c7f6f6a658a55..b8ca22185bc3c9dd33e4ca8f7c5833e2bb997eb1 100644 (file)
@@ -21,5 +21,5 @@ pub fn main() {
     let f: Fat<[isize; 3]> = Fat { ptr: [5, 6, 7] };
     let g: &Fat<[isize]> = &f;
     let h: &Fat<Fat<[isize]>> = &Fat { ptr: *g };
-    //~^ ERROR `[isize]: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
index 8fafd78d407969ec26ee9b2cdf998a2554789a3f..4a892753595a72cb4f3c7a76550878aa8848cd05 100644 (file)
@@ -16,22 +16,22 @@ impl Foo for [u8] {}
 
 fn test1<T: ?Sized + Foo>(t: &T) {
     let u: &Foo = t;
-    //~^ ERROR `T: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
 
 fn test2<T: ?Sized + Foo>(t: &T) {
     let v: &Foo = t as &Foo;
-    //~^ ERROR `T: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
 
 fn test3() {
     let _: &[&Foo] = &["hi"];
-    //~^ ERROR `str: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
 
 fn test4(x: &[u8]) {
     let _: &Foo = x as &Foo;
-    //~^ ERROR `[u8]: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
 
 fn main() { }
index bd5fd3ee3b71eff738117678b3e34f4cf2da068c..0679556743228c28af4c363ed92fb6b08e72ddc1 100644 (file)
@@ -15,9 +15,9 @@
 trait Foo<T> : Sized { fn take(self, x: &T) { } } // Note: T is sized
 
 impl Foo<[isize]> for usize { }
-//~^ ERROR `[isize]: std::marker::Sized` is not satisfied
+//~^ ERROR the size for value values of type
 
 impl Foo<isize> for [usize] { }
-//~^ ERROR `[usize]: std::marker::Sized` is not satisfied
+//~^ ERROR the size for value values of type
 
 pub fn main() { }
index 6a7a515ba5fbba41d5f773408bbef7d4f8300b92..10abb80a2f71b9072c0422bc60926ef4a29fec1b 100644 (file)
@@ -24,5 +24,5 @@ fn main() {
     //~^ ERROR `A` cannot be shared between threads safely [E0277]
 
     assert_send::<A>();
-    //~^ ERROR the trait bound `A: std::marker::Send` is not satisfied
+    //~^ ERROR `A` cannot be sent between threads safely [E0277]
 }
index faa27894806f8d81c7f049d90086403069e6dd97..135b466161d77a0cbe88c62d9314bf9da04eebcd 100644 (file)
@@ -30,14 +30,14 @@ fn assert_sized<T>() { }
 
 fn main() {
     assert_sized::<A>();
-    //~^ ERROR the trait bound `A: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 
     assert_sized::<Foo>();
-    //~^ ERROR the trait bound `A: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 
     assert_sized::<Bar<A>>();
-    //~^ ERROR the trait bound `A: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 
     assert_sized::<Bar<Bar<A>>>();
-    //~^ ERROR the trait bound `A: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
diff --git a/src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs b/src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs
new file mode 100644 (file)
index 0000000..7bcddbb
--- /dev/null
@@ -0,0 +1,17 @@
+// gate-test-irrefutable_let_patterns
+
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[allow(irrefutable_let_patterns)]
+fn main() {
+    if let _ = 5 {}
+    //~^ ERROR 15:12: 15:13: irrefutable if-let pattern [E0162]
+}
index 6d70f54edb4292a680f2ca0f5c0daf302934f987..56d64d77ee2581bccf1b10b293e23d3218defdd4 100644 (file)
@@ -16,15 +16,15 @@ fn main() {
     let _: () = (box |_: isize| {}) as Box<FnOnce(isize)>;
     //~^ ERROR mismatched types
     //~| expected type `()`
-    //~| found type `std::boxed::Box<std::ops::FnOnce(isize)>`
+    //~| found type `std::boxed::Box<dyn std::ops::FnOnce(isize)>`
     let _: () = (box |_: isize, isize| {}) as Box<Fn(isize, isize)>;
     //~^ ERROR mismatched types
     //~| expected type `()`
-    //~| found type `std::boxed::Box<std::ops::Fn(isize, isize)>`
+    //~| found type `std::boxed::Box<dyn std::ops::Fn(isize, isize)>`
     let _: () = (box || -> isize { unimplemented!() }) as Box<FnMut() -> isize>;
     //~^ ERROR mismatched types
     //~| expected type `()`
-    //~| found type `std::boxed::Box<std::ops::FnMut() -> isize>`
+    //~| found type `std::boxed::Box<dyn std::ops::FnMut() -> isize>`
 
     needs_fn(1);
     //~^ ERROR : std::ops::Fn<(isize,)>`
index 3d9d81471cb1e40da806c9348464d193ff9cfa98..f1fd617717a5ee5af533bf7bf3b51c44259688d2 100644 (file)
@@ -17,8 +17,8 @@ trait Foo {
 impl Foo for Baz {
     fn bar(&mut self, other: &Foo) {}
     //~^ ERROR method `bar` has an incompatible type for trait
-    //~| expected type `fn(&mut Baz, &mut Foo)`
-    //~| found type `fn(&mut Baz, &Foo)`
+    //~| expected type `fn(&mut Baz, &mut dyn Foo)`
+    //~| found type `fn(&mut Baz, &dyn Foo)`
 }
 
 fn main() {}
index 84452accc9a4ac4abec7e0134f6a81c628cbaf24..5212cbb004efadffd955977b1e68fd8367cf749e 100644 (file)
@@ -10,5 +10,5 @@
 
 fn main() {
     let _x = "test" as &::std::any::Any;
-//~^ ERROR `str: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
index 41349d7d7443b056bcaeb16498090e66b22ca71e..4756099ab95689c954112855ecfba28136c177e0 100644 (file)
@@ -15,7 +15,7 @@ fn dft_iter<'a, T>(arg1: Chunks<'a,T>, arg2: ChunksMut<'a,T>)
 {
     for
     &mut something
-//~^ ERROR `[T]: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
     in arg2
     {
     }
index 4996da057dd8ebc7be04358282479c5810b8a486..e7019ff7c0d21193caaa0a91119a31596622cdc1 100644 (file)
@@ -13,5 +13,5 @@
 
 fn main() {
     (|| Box::new(*(&[0][..])))();
-    //~^ ERROR `[{integer}]: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
index 33d68c121bf2674a9d11e854690129b1b5a284fe..9239ceb341fc6da523732dbd941e7ccf80195488 100644 (file)
@@ -12,7 +12,7 @@ pub trait AbstractRenderer {}
 
 fn _create_render(_: &()) ->
     AbstractRenderer
-//~^ ERROR: `AbstractRenderer + 'static: std::marker::Sized` is not satisfied
+//~^ ERROR the size for value values of type
 {
     match 0 {
         _ => unimplemented!()
index 3e21360721b6d87a9076a72e7efdea81fe9d0405..0b717ec641375d8a27af24804aef5a8ebf91263b 100644 (file)
@@ -11,7 +11,7 @@
 type FuncType<'f> = Fn(&isize) -> isize + 'f;
 
 fn ho_func(f: Option<FuncType>) {
-    //~^ ERROR: `for<'r> std::ops::Fn(&'r isize) -> isize: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
 
 fn main() {}
index c7564a9355bc5d19e3a15d85e4dbf7f3cca5896b..ccdd9db25c40a0b2e8d10b6de52ad49fda78bd1f 100644 (file)
@@ -8,5 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: `main` function is not allowed to have type parameters
+// error-pattern: `main` function is not allowed to have generic parameters
 fn main<T>() { }
index b02757fb5a3133acdf5f81f1fdda9a98f644d0bd..426657ac92e2c868a902d9edec48f5701ce410e4 100644 (file)
@@ -15,7 +15,7 @@ trait From<Src> {
 }
 
 trait To {
-    fn to<Dst>(  //~ ERROR `Self: std::marker::Sized` is not satisfied
+    fn to<Dst>(  //~ ERROR the size for value values of type
         self
     ) -> <Dst as From<Self>>::Result where Dst: From<Self> {
         From::from(self)
index d1a139e698e12e78e876973aad18e49a00524495..8b7f2d5a4588e3334ce464e0959643bf2cc52a19 100644 (file)
@@ -14,5 +14,5 @@ fn main() {}
 
 impl The {
     fn iceman(c: Vec<[i32]>) {}
-    //~^ ERROR the trait bound `[i32]: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
index 5eb0e4360fc93beeb208a294674ca837dded48d3..2d8d9c6565532c84ed65e24bb2b07a9e41c627f9 100644 (file)
@@ -10,7 +10,7 @@
 
 fn changer<'a>(mut things: Box<Iterator<Item=&'a mut u8>>) {
     for item in *things { *item = 0 }
-//~^ ERROR the trait bound `std::iter::Iterator<Item=&mut u8>: std::marker::Sized` is not satisfied
+//~^ ERROR the size for value values of type
 }
 
 fn main() {}
index 88197166ee08215b50af4204f551a269283c93e2..5282ce4bb8897dd43d09c6a61416193fe6b752e1 100644 (file)
@@ -11,6 +11,6 @@
 trait Foo {}
 
 impl<'a> Foo for Foo+'a {}
-//~^ ERROR the object type `Foo + 'a` automatically implements the trait `Foo`
+//~^ ERROR the object type `(dyn Foo + 'a)` automatically implements the trait `Foo`
 
 fn main() {}
index cb0baee0a8787d538d5f484dc4bd15f34014cf55..b4f952c87d4aae25a705d07395a95812b67fcf1e 100644 (file)
@@ -17,5 +17,5 @@ fn foo<T: Send>() {}
 
 fn main() {
     foo::<HashMap<Rc<()>, Rc<()>>>();
-    //~^ ERROR: `std::rc::Rc<()>: std::marker::Send` is not satisfied
+    //~^ ERROR `std::rc::Rc<()>` cannot be sent between threads safely
 }
index 0df84a436c0a936f0409dd159ac6f8934e09d428..cb199580b10dd182137a89de62dd8404dea87a63 100644 (file)
@@ -10,7 +10,7 @@
 
 struct Table {
     rows: [[String]],
-    //~^ ERROR the trait bound `[std::string::String]: std::marker::Sized` is not satisfied [E0277]
+    //~^ ERROR the size for value values of type
 }
 
 fn f(table: &Table) -> &[String] {
index 5feeb36b1e4d4f86a833270e19edbbedcbf2fbb8..d6b5c32982554a3055ff4e911552bc4cd994fc6b 100644 (file)
@@ -14,7 +14,7 @@
 
 impl Struct {
     pub fn function(funs: Vec<Fn() -> ()>) {}
-    //~^ ERROR the trait bound `std::ops::Fn() + 'static: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
 
 fn main() {}
index acd50bcf9e112fa0d608ba26e8f97f1c61b8f49b..74c68c50ae35aee6b8a773654d14a81c254f35d9 100644 (file)
@@ -10,8 +10,8 @@
 
 fn main() {
     static foo: Fn() -> u32 = || -> u32 {
-        //~^ ERROR: mismatched types
-        //~| ERROR: `std::ops::Fn() -> u32 + 'static: std::marker::Sized` is not satisfied
+        //~^ ERROR mismatched types
+        //~| ERROR the size for value values of type
         0
     };
 }
index 28180b05c8de8dcca986f5a6e34915d90f3df295..bc5567e1686d3ac16b35849c5d07f26cf8860c06 100644 (file)
@@ -10,7 +10,7 @@
 
 #[repr(packed)]
 pub struct Bad<T: ?Sized> {
-    data: T, //~ ERROR `T: std::marker::Sized` is not satisfied
+    data: T, //~ ERROR the size for value values of type
 }
 
 fn main() {}
index f34bef6224900620123f4fba8659e892f0efb9e6..6efc1f1024317ff8853c46faf4939921b845fb1f 100644 (file)
@@ -13,7 +13,7 @@
 trait Foo {
     const BAR: i32;
     fn foo(self) -> &'static i32 {
-        //~^ ERROR the trait bound `Self: std::marker::Sized` is not satisfied
+        //~^ ERROR the size for value values of type
         &<Self>::BAR
     }
 }
index e97e5a86a9d7d88567f4fd8249ddf996e9d83ddd..24db822f89ca0fc91cb443602836b7630b99712e 100644 (file)
@@ -17,5 +17,5 @@ fn size_of_copy<T: Copy+?Sized>() -> usize { mem::size_of::<T>() }
 fn main() {
     size_of_copy::<Misc+Copy>();
     //~^ ERROR only auto traits can be used as additional traits in a trait object
-    //~| ERROR the trait bound `Misc: std::marker::Copy` is not satisfied
+    //~| ERROR the trait bound `dyn Misc: std::marker::Copy` is not satisfied
 }
index c2e6a88a57bff7fedbc12259fc8e5c7229e9f88b..805b1a48a038012a67f2be38acb4ec080bcce1c3 100644 (file)
@@ -10,7 +10,7 @@
 
 enum E {
     V([Box<E>]),
-    //~^ ERROR the trait bound `[std::boxed::Box<E>]: std::marker::Sized` is not satisfied [E0277]
+    //~^ ERROR the size for value values of type
 }
 
 fn main() {}
index 896728b6da0f1df15d6b1a26f692556cd869f3cc..1b64d17bbeffe4b1de41f6c66aacbf2c465f68c1 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 fn _test(ref _p: str) {}
-//~^ ERROR the trait bound `str: std::marker::Sized` is not satisfied [E0277]
+//~^ ERROR the size for value values of type
 
 fn main() { }
index 15ca151c49a79b5079763d6b8029af21c17d88f8..0509a4387bae415f5999a640f5f55f477edd0626 100644 (file)
@@ -14,5 +14,5 @@ fn get_function<'a>() -> &'a Fn() -> Trait { panic!("") }
 
 fn main() {
     let t : &Trait = &get_function()();
-    //~^ ERROR cannot move a value of type Trait + 'static
+    //~^ ERROR cannot move a value of type (dyn Trait + 'static)
 }
index 31bc21c23ba5f08e1f2306a097717b9f4d041986..6207e669d0092ad790c994b743d3714bbe805a34 100644 (file)
@@ -9,8 +9,6 @@
 // except according to those terms.
 
 pub fn example(ref s: str) {}
-//~^ ERROR the trait bound `str: std::marker::Sized` is not satisfied
-//~| `str` does not have a constant size known at compile-time
-//~| the trait `std::marker::Sized` is not implemented for `str`
+//~^ ERROR the size for value values of type
 
 fn main() {}
index 06573b42b592db5c0dd61dc9ce62f311e39af538..2ab44433ede82151cd1e97320ad70b2127a26807 100644 (file)
 
 pub trait Foo {
     fn baz(_: Self::Target) where Self: Deref {}
-    //~^ ERROR `<Self as std::ops::Deref>::Target: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
 
 pub fn f(_: ToString) {}
-//~^ ERROR the trait bound `std::string::ToString + 'static: std::marker::Sized` is not satisfied
+//~^ ERROR the size for value values of type
 
 fn main() { }
index e9f62152888147aaaa75dcb2bc75818ec408778c..1e6366e068a890631cd9c74ff2ba1319eec7d23e 100644 (file)
@@ -11,7 +11,7 @@
 #![feature(fn_traits)]
 
 trait CallSingle<A, B> {
-    fn call(&self, a: A) -> B where Self: Fn(A) -> B;
+    fn call(&self, a: A) -> B where Self: Sized, Self: Fn(A) -> B;
 }
 
 impl<A, B, F: Fn(A) -> B> CallSingle<A, B> for F {
index b1d96f9b5277885dbb62dea04ef58c23e3b11f34..9b49886961d7b12b1655d172748e7c0c14521ba8 100644 (file)
@@ -18,5 +18,5 @@ fn foo(self: Box<isize>) { }
 
 fn main() {
     (&5isize as &Foo).foo();
-    //~^ ERROR: no method named `foo` found for type `&Foo` in the current scope
+    //~^ ERROR: no method named `foo` found for type `&dyn Foo` in the current scope
 }
index e14d9f3a35c84ff0fda9e7f8eeca93feb2eb796a..82d4666ce549ca1a68de9c2fb58ba98a40e995b4 100644 (file)
@@ -15,8 +15,8 @@ struct Struct {
 }
 
 fn new_struct(r: A+'static)
-    -> Struct { //~^  ERROR `A + 'static: std::marker::Sized` is not satisfied
-    //~^ ERROR `A + 'static: std::marker::Sized` is not satisfied
+    -> Struct { //~^ ERROR the size for value values of type
+    //~^ ERROR the size for value values of type
     Struct { r: r }
 }
 
index 95bbd4eccf4ff08cebdb83bcad077d0847a4ebbf..0c19780bcb4cab442589df9fd9f661689308f137 100644 (file)
@@ -34,5 +34,5 @@ struct A {
 
 fn main() {
     let a = A {v: box B{v: None} as Box<Foo+Send>};
-    //~^ ERROR `std::rc::Rc<std::cell::RefCell<A>>: std::marker::Send` is not satisfied
+    //~^ ERROR `std::rc::Rc<std::cell::RefCell<A>>` cannot be sent between threads safely
 }
index 2a86cdef9812fb88da2b80c8950634921f6648a9..3a0e66f58e0765e0fd48d7a6726ae4451eb1f2bc 100644 (file)
@@ -26,15 +26,15 @@ impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
 fn f<T>(val: T) {
     let t: S<T> = S(marker::PhantomData);
     let a = &t as &Gettable<T>;
-    //~^ ERROR : std::marker::Send` is not satisfied
-    //~^^ ERROR : std::marker::Copy` is not satisfied
+    //~^ ERROR `T` cannot be sent between threads safely
+    //~| ERROR : std::marker::Copy` is not satisfied
 }
 
 fn g<T>(val: T) {
     let t: S<T> = S(marker::PhantomData);
     let a: &Gettable<T> = &t;
-    //~^ ERROR : std::marker::Send` is not satisfied
-    //~^^ ERROR : std::marker::Copy` is not satisfied
+    //~^ ERROR `T` cannot be sent between threads safely
+    //~| ERROR : std::marker::Copy` is not satisfied
 }
 
 fn foo<'a>() {
index dd77c2c138f4622df9b7a129959b05fb95e37d46..43c212b2af58278d8e7efe365edd2254d322e9e4 100644 (file)
@@ -18,5 +18,5 @@ fn bar<F:FnOnce() + Send>(_: F) { }
 fn main() {
     let x = Rc::new(3);
     bar(move|| foo(x));
-    //~^ ERROR : std::marker::Send` is not satisfied
+    //~^ ERROR `std::rc::Rc<usize>` cannot be sent between threads safely
 }
index a84eae0bfdae86c23b76bc403a58953f8ade4b48..82b97878549032dff3dc57a10051f0f7766d2628 100644 (file)
@@ -20,11 +20,12 @@ trait Message : Send { }
 
 fn object_ref_with_static_bound_not_ok() {
     assert_send::<&'static (Dummy+'static)>();
-    //~^ ERROR `Dummy + 'static` cannot be shared between threads safely [E0277]
+    //~^ ERROR `(dyn Dummy + 'static)` cannot be shared between threads safely [E0277]
 }
 
 fn box_object_with_no_bound_not_ok<'a>() {
-    assert_send::<Box<Dummy>>(); //~ ERROR : std::marker::Send` is not satisfied
+    assert_send::<Box<Dummy>>();
+    //~^ ERROR `dyn Dummy` cannot be sent between threads safely
 }
 
 fn object_with_send_bound_ok() {
index 66865bbcc7ee12f162c7529f53bacd385e79b40f..853630aa41628a90f2c98d35dab6ee746a328d01 100644 (file)
@@ -18,7 +18,7 @@ trait Dummy { }
 // careful with object types, who knows what they close over...
 fn test51<'a>() {
     assert_send::<&'a Dummy>();
-    //~^ ERROR `Dummy + 'a` cannot be shared between threads safely [E0277]
+    //~^ ERROR `(dyn Dummy + 'a)` cannot be shared between threads safely [E0277]
 }
 fn test52<'a>() {
     assert_send::<&'a (Dummy+Sync)>();
@@ -37,7 +37,7 @@ fn test61() {
 // them not ok
 fn test_71<'a>() {
     assert_send::<Box<Dummy+'a>>();
-    //~^ ERROR : std::marker::Send` is not satisfied
+    //~^ ERROR `(dyn Dummy + 'a)` cannot be sent between threads safely
 }
 
 fn main() { }
index 51bc587d74ff83e5d84d179886a35fec57fcca2b..0265f888e7c317411a728d9e0021bc80add29c0d 100644 (file)
@@ -15,11 +15,12 @@ trait Dummy { }
 
 fn test50() {
     assert_send::<&'static Dummy>();
-    //~^ ERROR `Dummy + 'static` cannot be shared between threads safely [E0277]
+    //~^ ERROR `(dyn Dummy + 'static)` cannot be shared between threads safely [E0277]
 }
 
 fn test53() {
-    assert_send::<Box<Dummy>>(); //~ ERROR : std::marker::Send` is not satisfied
+    assert_send::<Box<Dummy>>();
+    //~^ ERROR `dyn Dummy` cannot be sent between threads safely
 }
 
 // ...unless they are properly bounded
index 583381a1c28f5b23fc9753f8e2ef25f9b1dde529..e48460a87537f2d5aa62d2d41c6fb0e8d375696e 100644 (file)
@@ -19,7 +19,8 @@ fn assert_send<T:Send>() { }
 
 // but not if they own a bad thing
 fn test40() {
-    assert_send::<Box<*mut u8>>(); //~ ERROR : std::marker::Send` is not satisfied
+    assert_send::<Box<*mut u8>>();
+    //~^ ERROR `*mut u8` cannot be sent between threads safely
 }
 
 fn main() { }
index c717d1a72e05d31c536274cee20a703deb0062b2..99b995b0906b4edd66f0a2ee9a1770fd4a4c1389 100644 (file)
@@ -14,7 +14,7 @@ fn assert_send<T:Send>() { }
 
 fn test71<'a>() {
     assert_send::<*mut &'a isize>();
-    //~^ ERROR `*mut &'a isize: std::marker::Send` is not satisfied
+    //~^ ERROR `*mut &'a isize` cannot be sent between threads safely
 }
 
 fn main() {
index 49a52204295e505aa3e6b8762c6c7a8ce02974fe..bd390108bd8f3c40468fc1e122bae926a345f8c3 100644 (file)
@@ -50,6 +50,8 @@ fn test() {
         <Foo>::trait_deprecated_text(&foo);
         <Foo as Trait>::trait_deprecated_text(&foo);
 
+        deprecated_future(); // Fine; no error.
+
         deprecated_unstable();
         //~^ ERROR use of unstable library feature
         Trait::trait_deprecated_unstable(&foo);
@@ -218,6 +220,10 @@ pub fn deprecated() {}
     #[rustc_deprecated(since = "1.0.0", reason = "text")]
     pub fn deprecated_text() {}
 
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_deprecated(since = "99.99.99", reason = "text")]
+    pub fn deprecated_future() {}
+
     #[unstable(feature = "test_feature", issue = "0")]
     pub fn unstable() {}
     #[unstable(feature = "test_feature", reason = "text", issue = "0")]
@@ -338,6 +344,8 @@ fn test() {
         <Foo>::trait_deprecated_text(&foo);
         <Foo as Trait>::trait_deprecated_text(&foo);
 
+        deprecated_future();
+
         unstable();
         foo.method_unstable();
         Foo::method_unstable(&foo);
index 9dcf902a69f916c7f343ebcd3de73f1853519ff9..e8ff9e817af2ca9d67bda5eda4bb9d4a2731fea1 100644 (file)
@@ -25,5 +25,5 @@ fn main() {
     let x: Box<HashMap<isize, isize>> = box HashMap::new();
     let x: Box<Map<isize, isize>> = x;
     let y: Box<Map<usize, isize>> = Box::new(x);
-    //~^ ERROR `std::boxed::Box<Map<isize, isize>>: Map<usize, isize>` is not satisfied
+    //~^ ERROR `std::boxed::Box<dyn Map<isize, isize>>: Map<usize, isize>` is not satisfied
 }
index 334952cefa6e02f9612f3e761db590f966a07159..6825963c486470f69e41692e8e1a8f7058ef1fd0 100644 (file)
@@ -33,7 +33,7 @@ fn foo(x: Port<()>) -> foo {
     let x = foo(Port(Rc::new(())));
 
     thread::spawn(move|| {
-        //~^ ERROR `std::rc::Rc<()>: std::marker::Send` is not satisfied
+        //~^ ERROR `std::rc::Rc<()>` cannot be sent between threads safely
         let y = x;
         println!("{:?}", y);
     });
index 902710e96e274fbc0ffc8a83d61e739741ff1ded..83f19ed19efc22a5c0f3c4eb00388e6ea0ad45a9 100644 (file)
@@ -24,5 +24,5 @@ fn bar<T: Send>(_: T) {}
 fn main() {
     let x = Foo::A(NoSend);
     bar(x);
-    //~^ ERROR `NoSend: std::marker::Send` is not satisfied
+    //~^ ERROR `NoSend` cannot be sent between threads safely
 }
index f31d3787334916bffb1565d63bd1eaf5df7067a8..d3616d144229c648e8731f9034c7f2ce92946227 100644 (file)
@@ -15,5 +15,5 @@ fn bar<T: Send>(_: T) {}
 fn main() {
     let x = Rc::new(5);
     bar(x);
-    //~^ ERROR `std::rc::Rc<{integer}>: std::marker::Send` is not satisfied
+    //~^ ERROR `std::rc::Rc<{integer}>` cannot be sent between threads safely
 }
index b2ca4f9f5db16bb76a749cf8478733ded2a68b5e..d38d993e7e8e6f2af7b56da73b498f88b12b981b 100644 (file)
@@ -23,5 +23,5 @@ fn bar<T: Send>(_: T) {}
 fn main() {
     let x = Foo { a: 5 };
     bar(x);
-    //~^ ERROR `Foo: std::marker::Send` is not satisfied
+    //~^ ERROR `Foo` cannot be sent between threads safely
 }
index a51a9e518ce5fe7e0d7aac6fd9f6b9b7922ac72f..2a6e148ca791157c491d92fecbcfe9e1951b0708 100644 (file)
@@ -61,22 +61,22 @@ pub unsafe fn test_Foo_cxchg(p: &mut Foo, v: Foo) {
 
 pub unsafe fn test_Bar_load(p: &mut Bar, v: Bar) {
     intrinsics::atomic_load(p);
-    //~^ ERROR expected basic integer type, found `&std::ops::Fn()`
+    //~^ ERROR expected basic integer type, found `&dyn std::ops::Fn()`
 }
 
 pub unsafe fn test_Bar_store(p: &mut Bar, v: Bar) {
     intrinsics::atomic_store(p, v);
-    //~^ ERROR expected basic integer type, found `&std::ops::Fn()`
+    //~^ ERROR expected basic integer type, found `&dyn std::ops::Fn()`
 }
 
 pub unsafe fn test_Bar_xchg(p: &mut Bar, v: Bar) {
     intrinsics::atomic_xchg(p, v);
-    //~^ ERROR expected basic integer type, found `&std::ops::Fn()`
+    //~^ ERROR expected basic integer type, found `&dyn std::ops::Fn()`
 }
 
 pub unsafe fn test_Bar_cxchg(p: &mut Bar, v: Bar) {
     intrinsics::atomic_cxchg(p, v, v);
-    //~^ ERROR expected basic integer type, found `&std::ops::Fn()`
+    //~^ ERROR expected basic integer type, found `&dyn std::ops::Fn()`
 }
 
 pub unsafe fn test_Quux_load(p: &mut Quux, v: Quux) {
index 7107211fc914b47479b2569515fee614191cca08..d750851b719e4e691a7691c24255a2480503c6df 100644 (file)
@@ -18,6 +18,6 @@ fn assert<T: UnwindSafe + ?Sized>() {}
 
 fn main() {
     assert::<Rc<RefCell<i32>>>();
-    //~^ ERROR `std::cell::UnsafeCell<i32>: std::panic::RefUnwindSafe` is not satisfied
-    //~^^ ERROR `std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied
+    //~^ ERROR the type `std::cell::UnsafeCell<i32>` may contain interior mutability and a
+    //~| ERROR the type `std::cell::UnsafeCell<usize>` may contain interior mutability and a
 }
index 76c34e4dc0b448613ddaef1d2041ad8bc15f18dd..cd27b274258ea3d49619ef0622576c6cf22a003e 100644 (file)
@@ -18,6 +18,6 @@ fn assert<T: UnwindSafe + ?Sized>() {}
 
 fn main() {
     assert::<Arc<RefCell<i32>>>();
-    //~^ ERROR `std::cell::UnsafeCell<i32>: std::panic::RefUnwindSafe` is not satisfied
-    //~^^ ERROR `std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied
+    //~^ ERROR the type `std::cell::UnsafeCell<i32>` may contain interior mutability and a
+    //~| ERROR the type `std::cell::UnsafeCell<usize>` may contain interior mutability and a
 }
index 177a43e2a7f71650a74955496b37f75cfc1b508f..956eca432c5f06f1602ca0e1a86723c62cce462c 100644 (file)
@@ -17,6 +17,6 @@ fn assert<T: UnwindSafe + ?Sized>() {}
 
 fn main() {
     assert::<&RefCell<i32>>();
-    //~^ ERROR `std::cell::UnsafeCell<i32>: std::panic::RefUnwindSafe` is not satisfied
-    //~^^ ERROR `std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied
+    //~^ ERROR the type `std::cell::UnsafeCell<i32>` may contain interior mutability and a
+    //~| ERROR the type `std::cell::UnsafeCell<usize>` may contain interior mutability and a
 }
index f03e1d545a8083786f324118f27ebc25eb9f9a94..d0ca1db52120480d29447df6491d6f3190516b26 100644 (file)
@@ -17,6 +17,6 @@ fn assert<T: UnwindSafe + ?Sized>() {}
 
 fn main() {
     assert::<*mut RefCell<i32>>();
-    //~^ ERROR `std::cell::UnsafeCell<i32>: std::panic::RefUnwindSafe` is not satisfied
-    //~^^ ERROR `std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied
+    //~^ ERROR the type `std::cell::UnsafeCell<i32>` may contain interior mutability and a
+    //~| ERROR the type `std::cell::UnsafeCell<usize>` may contain interior mutability and a
 }
index ece8fa7dc47bb12da8a4ffdbdad81c48a9a513e7..0ebf3d3fed7b5dcfb97c3764e3319c68148b15d1 100644 (file)
@@ -16,5 +16,6 @@
 fn assert<T: UnwindSafe + ?Sized>() {}
 
 fn main() {
-    assert::<&mut i32>(); //~ ERROR: UnwindSafe` is not satisfied
+    assert::<&mut i32>();
+    //~^ ERROR the type `&mut i32` may not be safely transferred across an unwind boundary
 }
index 8babc734c84cc13afdf33ec6fcaf74f757461362..30f8d5e2f45698c5f37d1dd2b8b33d3f1c59c88a 100644 (file)
@@ -14,5 +14,5 @@
 trait Foo {}
 fn take_foo<F:Foo>(f: F) {}
 fn take_object(f: Box<Foo>) { take_foo(f); }
-//~^ ERROR `std::boxed::Box<Foo>: Foo` is not satisfied
+//~^ ERROR `std::boxed::Box<dyn Foo>: Foo` is not satisfied
 fn main() {}
index 36356cb7d527e2442b1bfdccdf7ca520acc1bc49..e575bbb6ceab102fe8f29e008412915a22962641 100644 (file)
@@ -22,7 +22,7 @@ trait Baz {
 }
 
 fn use_bar(t: Box<Bar>) {
-    t.bar() //~ ERROR cannot move a value of type Bar
+    t.bar() //~ ERROR cannot move a value of type (dyn Bar + 'static)
 }
 
 fn main() { }
index c25616c54354d9f0d856927e915e1f383f5c83ba..6019369aa2ebb5111d556194a70186b9974e09c1 100644 (file)
@@ -19,19 +19,19 @@ pub trait PubTr: PrivTr {}
 
     pub macro mac1() {
         let _: Box<PubTr<AssocTy = u8>>;
-        //~^ ERROR type `priv_trait::PubTr<AssocTy=u8> + '<empty>` is private
-        //~| ERROR type `priv_trait::PubTr<AssocTy=u8> + '<empty>` is private
+        //~^ ERROR type `(dyn priv_trait::PubTr<AssocTy=u8> + '<empty>)` is private
+        //~| ERROR type `(dyn priv_trait::PubTr<AssocTy=u8> + '<empty>)` is private
         type InSignatureTy2 = Box<PubTr<AssocTy = u8>>;
-        //~^ ERROR type `priv_trait::PubTr<AssocTy=u8> + 'static` is private
+        //~^ ERROR type `(dyn priv_trait::PubTr<AssocTy=u8> + 'static)` is private
         trait InSignatureTr2: PubTr<AssocTy = u8> {}
         //~^ ERROR trait `priv_trait::PrivTr` is private
     }
     pub macro mac2() {
         let _: Box<PrivTr<AssocTy = u8>>;
-        //~^ ERROR type `priv_trait::PrivTr<AssocTy=u8> + '<empty>` is private
-        //~| ERROR type `priv_trait::PrivTr<AssocTy=u8> + '<empty>` is private
+        //~^ ERROR type `(dyn priv_trait::PrivTr<AssocTy=u8> + '<empty>)` is private
+        //~| ERROR type `(dyn priv_trait::PrivTr<AssocTy=u8> + '<empty>)` is private
         type InSignatureTy1 = Box<PrivTr<AssocTy = u8>>;
-        //~^ ERROR type `priv_trait::PrivTr<AssocTy=u8> + 'static` is private
+        //~^ ERROR type `(dyn priv_trait::PrivTr<AssocTy=u8> + 'static)` is private
         trait InSignatureTr1: PrivTr<AssocTy = u8> {}
         //~^ ERROR trait `priv_trait::PrivTr` is private
     }
index 5af8b063c1629f12e0fb6c3f348337b1bef51357..3ca8b1eb2ed3a3d61b36484b2deb13d96a512d41 100644 (file)
@@ -129,7 +129,7 @@ fn main() {
     m::leak_anon2(); //~ ERROR type `m::Priv` is private
     m::leak_anon3(); //~ ERROR type `m::Priv` is private
 
-    m::leak_dyn1(); //~ ERROR type `m::Trait + 'static` is private
+    m::leak_dyn1(); //~ ERROR type `(dyn m::Trait + 'static)` is private
     m::leak_dyn2(); //~ ERROR type `m::Priv` is private
     m::leak_dyn3(); //~ ERROR type `m::Priv` is private
 
index 58794e3b35d531c897a3eee98be7e5ca5e33961b..ed26204bbe10920d39a5896ae8c9d0e9a949ed03 100644 (file)
@@ -22,5 +22,5 @@ pub fn main() {
     // Unsized type.
     let arr: &[_] = &[1, 2, 3];
     let range = *arr..;
-    //~^ ERROR `[{integer}]: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
index 32f9b83b6e2c77f556439d8e5cbf4851f1ecca11..78d3702b449caa7613cb167d13d30c4005a2f825 100644 (file)
 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
 struct AllTheRanges {
     a: Range<usize>,
-    //~^ ERROR PartialOrd
-    //~^^ ERROR Ord
+    //~^ ERROR can't compare
+    //~| ERROR Ord
     b: RangeTo<usize>,
-    //~^ ERROR PartialOrd
-    //~^^ ERROR Ord
+    //~^ ERROR can't compare
+    //~| ERROR Ord
     c: RangeFrom<usize>,
-    //~^ ERROR PartialOrd
-    //~^^ ERROR Ord
+    //~^ ERROR can't compare
+    //~| ERROR Ord
     d: RangeFull,
-    //~^ ERROR PartialOrd
-    //~^^ ERROR Ord
+    //~^ ERROR can't compare
+    //~| ERROR Ord
     e: RangeInclusive<usize>,
-    //~^ ERROR PartialOrd
-    //~^^ ERROR Ord
+    //~^ ERROR can't compare
+    //~| ERROR Ord
     f: RangeToInclusive<usize>,
-    //~^ ERROR PartialOrd
-    //~^^ ERROR Ord
+    //~^ ERROR can't compare
+    //~| ERROR Ord
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/should-fail-no_gate_irrefutable_if_let_pattern.rs b/src/test/compile-fail/should-fail-no_gate_irrefutable_if_let_pattern.rs
new file mode 100644 (file)
index 0000000..8c9a24f
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// should-fail-irrefutable_let_patterns
+fn main() {
+    if let _ = 5 {}
+    //~^ ERROR irrefutable if-let pattern [E0162]
+}
diff --git a/src/test/compile-fail/should-fail-with_gate_irrefutable_pattern_deny.rs b/src/test/compile-fail/should-fail-with_gate_irrefutable_pattern_deny.rs
new file mode 100644 (file)
index 0000000..6f95f10
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(irrefutable_let_patterns)]
+
+// should-fail-irrefutable_let_patterns_with_gate
+fn main() {
+    if let _ = 5 {}
+    //~^ ERROR irrefutable if-let pattern [irrefutable_let_patterns]
+}
index 2b2c23a3ce4e92c88fee61c0c242775e1a65cc7d..b5f1ffb977ed630e85a2bebd1c8c09a67a7fb943 100644 (file)
@@ -10,5 +10,5 @@
 
 pub fn main() {
     let s: &str = "hello";
-    let c: u8 = s[4]; //~ ERROR `str: std::ops::Index<{integer}>` is not satisfied
+    let c: u8 = s[4]; //~ ERROR the type `str` cannot be indexed by `{integer}`
 }
index 219fcdfd7026531d935abbe1354da050de769ef0..cc5fd7e3f24d82fd64dcd99b7ec1a35810b90463 100644 (file)
@@ -12,10 +12,10 @@ fn bot<T>() -> T { loop {} }
 
 fn mutate(s: &mut str) {
     s[1..2] = bot();
-    //~^ ERROR `str: std::marker::Sized` is not satisfied
-    //~| ERROR `str: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
+    //~| ERROR the size for value values of type
     s[1usize] = bot();
-    //~^ ERROR `str: std::ops::IndexMut<usize>` is not satisfied
+    //~^ ERROR the type `str` cannot be mutably indexed by `usize`
 }
 
 pub fn main() {}
index c857790e342d0270921b9028c0b0329c2a5b22ae..b8557cb79e38743d5008faa28819f2cc39ac122c 100644 (file)
@@ -56,6 +56,6 @@ fn foo<'z>() where &'z (): Sized {
     //[normal]~| found type `fn() {foo::<'static>}`
 
     <str as Foo<u8>>::bar;
-    //[verbose]~^ ERROR `str: std::marker::Sized` is not satisfied
-    //[normal]~^^ ERROR `str: std::marker::Sized` is not satisfied
+    //[verbose]~^ ERROR the size for value values of type
+    //[normal]~^^ ERROR the size for value values of type
 }
index 983c66ec1c40fba449e4ba1490512cd00521d9b3..89fddf1f65f0240ea7f391358ea8d43ffc98d866 100644 (file)
@@ -15,7 +15,7 @@ fn dummy(&self) { }
 // This should emit the less confusing error, not the more confusing one.
 
 fn foo(_x: Foo + Send) {
-    //~^ ERROR the trait bound `Foo + std::marker::Send + 'static: std::marker::Sized` is not
+    //~^ ERROR the size for value values of type
 }
 
 fn main() { }
index be0f7dd4e1cd73f34d35a8b2c7f1cbf3443eda21..f8e4f0d596e20d3a005514552b5ea0eecaa42e64 100644 (file)
@@ -110,9 +110,9 @@ fn check_assoc_const() {
     // A, B, C are resolved as inherent items, their traits don't need to be in scope
     C::A; //~ ERROR associated constant `A` is private
           //~^ ERROR the trait `assoc_const::C` cannot be made into an object
-          //~| ERROR the trait bound `assoc_const::C: assoc_const::A` is not satisfied
+          //~| ERROR the trait bound `dyn assoc_const::C: assoc_const::A` is not satisfied
     C::B; // ERROR the trait `assoc_const::C` cannot be made into an object
-          //~^ ERROR the trait bound `assoc_const::C: assoc_const::B` is not satisfied
+          //~^ ERROR the trait bound `dyn assoc_const::C: assoc_const::B` is not satisfied
     C::C; // OK
 }
 
index 8014f92e1734438b5765e21caaaeb77f01395927..a272686c535738ab38071e163c12b2c14cc47d73 100644 (file)
@@ -31,8 +31,8 @@ fn dummy() {
     impl !Send for TestType {}
 
     Outer(TestType);
-    //~^ ERROR `dummy::TestType: std::marker::Send` is not satisfied
-    //~| ERROR `dummy::TestType: std::marker::Send` is not satisfied
+    //~^ ERROR `dummy::TestType` cannot be sent between threads safely
+    //~| ERROR `dummy::TestType` cannot be sent between threads safely
 }
 
 fn dummy1b() {
@@ -40,7 +40,7 @@ fn dummy1b() {
     impl !Send for TestType {}
 
     is_send(TestType);
-    //~^ ERROR `dummy1b::TestType: std::marker::Send` is not satisfied
+    //~^ ERROR `dummy1b::TestType` cannot be sent between threads safely
 }
 
 fn dummy1c() {
@@ -48,7 +48,7 @@ fn dummy1c() {
     impl !Send for TestType {}
 
     is_send((8, TestType));
-    //~^ ERROR `dummy1c::TestType: std::marker::Send` is not satisfied
+    //~^ ERROR `dummy1c::TestType` cannot be sent between threads safely
 }
 
 fn dummy2() {
@@ -56,7 +56,7 @@ fn dummy2() {
     impl !Send for TestType {}
 
     is_send(Box::new(TestType));
-    //~^ ERROR `dummy2::TestType: std::marker::Send` is not satisfied
+    //~^ ERROR `dummy2::TestType` cannot be sent between threads safely
 }
 
 fn dummy3() {
@@ -64,7 +64,7 @@ fn dummy3() {
     impl !Send for TestType {}
 
     is_send(Box::new(Outer2(TestType)));
-    //~^ ERROR `dummy3::TestType: std::marker::Send` is not satisfied
+    //~^ ERROR `dummy3::TestType` cannot be sent between threads safely
 }
 
 fn main() {
@@ -74,5 +74,5 @@ impl !Send for TestType {}
     // This will complain about a missing Send impl because `Sync` is implement *just*
     // for T that are `Send`. Look at #20366 and #19950
     is_sync(Outer2(TestType));
-    //~^ ERROR `main::TestType: std::marker::Send` is not satisfied
+    //~^ ERROR `main::TestType` cannot be sent between threads safely
 }
index 3fc0d638dd6f1880be39caa81b4c71bdb4e4e35c..559871af72ed630e8b0e5d32f38930a077d974e8 100644 (file)
@@ -33,7 +33,7 @@ fn same_as(&self, t: u64) -> bool { *self == (t as i64) }
 impl CompareToInts for i64 { }
 
 fn with_obj(c: &CompareToInts) -> bool {
-    c.same_as(22) //~ ERROR `CompareToInts: CompareTo<i32>` is not satisfied
+    c.same_as(22) //~ ERROR `dyn CompareToInts: CompareTo<i32>` is not satisfied
 }
 
 fn with_trait<C:CompareToInts>(c: &C) -> bool {
@@ -41,7 +41,7 @@ fn with_trait<C:CompareToInts>(c: &C) -> bool {
 }
 
 fn with_ufcs1<C:CompareToInts>(c: &C) -> bool {
-    CompareToInts::same_as(c, 22) //~ ERROR `CompareToInts: CompareTo<i32>` is not satisfied
+    CompareToInts::same_as(c, 22) //~ ERROR `dyn CompareToInts: CompareTo<i32>` is not satisfied
 }
 
 fn with_ufcs2<C:CompareToInts>(c: &C) -> bool {
index aabf0d26d5ba7db921d144fd43df73d2ab35edb5..3f2bd2ffabf4bad00cd416e10feec06f5092466d 100644 (file)
@@ -59,25 +59,25 @@ pub fn main() {
 
     // unsize trait
     let x: &Bar = &Bar;
-    let _ = x as &Foo; //~ERROR trivial cast: `&Bar` as `&Foo`
-    let _ = x as *const Foo; //~ERROR trivial cast: `&Bar` as `*const Foo`
+    let _ = x as &Foo; //~ERROR trivial cast: `&Bar` as `&dyn Foo`
+    let _ = x as *const Foo; //~ERROR trivial cast: `&Bar` as `*const dyn Foo`
     let _: &Foo = x;
     let _: *const Foo = x;
 
     let x: &mut Bar = &mut Bar;
-    let _ = x as &mut Foo; //~ERROR trivial cast: `&mut Bar` as `&mut Foo`
-    let _ = x as *mut Foo; //~ERROR trivial cast: `&mut Bar` as `*mut Foo`
+    let _ = x as &mut Foo; //~ERROR trivial cast: `&mut Bar` as `&mut dyn Foo`
+    let _ = x as *mut Foo; //~ERROR trivial cast: `&mut Bar` as `*mut dyn Foo`
     let _: &mut Foo = x;
     let _: *mut Foo = x;
 
     let x: Box<Bar> = Box::new(Bar);
-    let _ = x as Box<Foo>; //~ERROR trivial cast: `std::boxed::Box<Bar>` as `std::boxed::Box<Foo>`
+    let _ = x as Box<Foo>; //~ERROR `std::boxed::Box<Bar>` as `std::boxed::Box<dyn Foo>`
     let x: Box<Bar> = Box::new(Bar);
     let _: Box<Foo> = x;
 
     // functions
     fn baz(_x: i32) {}
-    let _ = &baz as &Fn(i32); //~ERROR trivial cast: `&fn(i32) {main::baz}` as `&std::ops::Fn(i32)`
+    let _ = &baz as &Fn(i32); //~ERROR `&fn(i32) {main::baz}` as `&dyn std::ops::Fn(i32)`
     let _: &Fn(i32) = &baz;
     let x = |_x: i32| {};
     let _ = &x as &Fn(i32); //~ERROR trivial cast
index 4295d08a4709c701eaa8e63336ff5fac086e9e4d..7e93f626cfcfb38ef65c00769270576ecb249950 100644 (file)
@@ -33,7 +33,7 @@ fn main() {
         //~^ ERROR mismatched types
         //~| Perhaps two different versions of crate `crate_a1`
         //~| expected trait `main::a::Bar`
-        //~| expected type `std::boxed::Box<main::a::Bar + 'static>`
-        //~| found type `std::boxed::Box<main::a::Bar>`
+        //~| expected type `std::boxed::Box<(dyn main::a::Bar + 'static)>`
+        //~| found type `std::boxed::Box<dyn main::a::Bar>`
     }
 }
index 09687724656fa8febe373f1f01ed750e45efed27..08988353886451992f644ceac9ab7dcb2ca2a85c 100644 (file)
@@ -23,5 +23,5 @@ fn main() {
     let x: i32 = 5;
     let y = x as MyAdd<i32>;
     //~^ ERROR E0038
-    //~| ERROR cast to unsized type: `i32` as `MyAdd<i32>`
+    //~| ERROR cast to unsized type: `i32` as `dyn MyAdd<i32>`
 }
index 853718f1e77d08ddcc68ca765eaa4173550cc76e..65438e5df8e08e73a2256c0f961038b76ff19227 100644 (file)
@@ -27,5 +27,5 @@ fn is_send<T: Send>() {}
 fn main() {
     is_send::<MySendable>();
     is_send::<MyNotSendable>();
-    //~^ ERROR `MyNotSendable: std::marker::Send` is not satisfied
+    //~^ ERROR `MyNotSendable` cannot be sent between threads safely
 }
index a238eaf052508460677a4c59f893754a2abf70f3..a9a2a3c4c92a11064698d939d08873d183f41f8b 100644 (file)
 #![feature(untagged_unions)]
 
 union U {
-    a: str, //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
+    a: str,
+    //~^ ERROR the size for value values of type
+
     b: u8,
 }
 
 union W {
     a: u8,
-    b: str, //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
+    b: str,
+    //~^ ERROR the size for value values of type
 }
 
 fn main() {}
index 3dcc7d248d72db316eb7848174d9f19ae48c38de..736794ac5384e0c768404c791b9ce6b2dcfaf34c 100644 (file)
@@ -9,5 +9,6 @@
 // except according to those terms.
 
 fn bar<T: Sized>() { }
-fn foo<T: ?Sized>() { bar::<T>() } //~ ERROR `T: std::marker::Sized` is not satisfied
+fn foo<T: ?Sized>() { bar::<T>() }
+//~^ ERROR the size for value values of type
 fn main() { }
index 5d791215f36c60108c3819e98d69d498b252a7b5..f9702e29f1dc36ea44cc03fda326ca6859c58523 100644 (file)
@@ -15,7 +15,7 @@ fn not_sized<T: ?Sized>() { }
 enum Foo<U> { FooSome(U), FooNone }
 fn foo1<T>() { not_sized::<Foo<T>>() } // Hunky dory.
 fn foo2<T: ?Sized>() { not_sized::<Foo<T>>() }
-//~^ ERROR `T: std::marker::Sized` is not satisfied
+//~^ ERROR the size for value values of type
 //
 // Not OK: `T` is not sized.
 
index 4d0774f2ce44157743fbdc6135a37874b7808eb7..03d3d98b59f012d62b54c16c73817128db8da673 100644 (file)
@@ -14,7 +14,8 @@
 
 struct S5<Y>(Y);
 
-impl<X: ?Sized> S5<X> { //~ ERROR E0277
+impl<X: ?Sized> S5<X> {
+    //~^ ERROR the size for value values of type
 }
 
 fn main() { }
index bbefb2fcecd80f7ba78fcd03abedf8d7fa702e7e..8cb1f760664de469aec6c0572f6ab7086c1d619e 100644 (file)
@@ -15,14 +15,14 @@ fn not_sized<T: ?Sized>() { }
 struct Foo<T> { data: T }
 fn foo1<T>() { not_sized::<Foo<T>>() } // Hunky dory.
 fn foo2<T: ?Sized>() { not_sized::<Foo<T>>() }
-//~^ ERROR `T: std::marker::Sized` is not satisfied
+//~^ ERROR the size for value values of type
 //
 // Not OK: `T` is not sized.
 
 struct Bar<T: ?Sized> { data: T }
 fn bar1<T: ?Sized>() { not_sized::<Bar<T>>() }
 fn bar2<T: ?Sized>() { is_sized::<Bar<T>>() }
-//~^ ERROR `T: std::marker::Sized` is not satisfied
+//~^ ERROR the size for value values of type
 //
 // Not OK: `Bar<T>` is not sized, but it should be.
 
index c919bdf924f6566bb8b707451d7b860e3e397e31..b3610a4c9b9b64b8f0ddd5921e3e181fa9649ec7 100644 (file)
@@ -17,7 +17,8 @@ trait T3<Z: ?Sized> {
 
 struct S5<Y>(Y);
 
-impl<X: ?Sized> T3<X> for S5<X> { //~ ERROR E0277
+impl<X: ?Sized> T3<X> for S5<X> {
+    //~^ ERROR the size for value values of type
 }
 
 fn main() { }
index ad5e4c2daef9ea010cc8eb8f086f7a2721195e53..50a058a4338d8d56f9813d32dbedddce449a2cb9 100644 (file)
@@ -16,7 +16,7 @@ trait T2<Z> {
 }
 struct S4<Y: ?Sized>(Box<Y>);
 impl<X: ?Sized> T2<X> for S4<X> {
-    //~^ ERROR `X: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
 
 fn main() { }
index e96e0ea3aec3623ec0d57b2a3e4aae3927c2adaf..945f20b28779ed9963fd552ca7c47a28683f830f 100644 (file)
@@ -15,7 +15,7 @@
 // Unbounded.
 fn f1<X: ?Sized>(x: &X) {
     f2::<X>(x);
-    //~^ ERROR `X: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
 fn f2<X>(x: &X) {
 }
@@ -26,7 +26,7 @@ fn foo(&self) { }
 }
 fn f3<X: ?Sized + T>(x: &X) {
     f4::<X>(x);
-    //~^ ERROR `X: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
 fn f4<X: T>(x: &X) {
 }
@@ -41,20 +41,20 @@ struct S<X: ?Sized> {
 
 fn f8<X: ?Sized>(x1: &S<X>, x2: &S<X>) {
     f5(x1);
-    //~^ ERROR `X: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
     f6(x2); // ok
 }
 
 // Test some tuples.
 fn f9<X: ?Sized>(x1: Box<S<X>>) {
     f5(&(*x1, 34));
-    //~^ ERROR `X: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
 
 fn f10<X: ?Sized>(x1: Box<S<X>>) {
     f5(&(32, *x1));
-    //~^ ERROR `X: std::marker::Sized` is not satisfied
-    //~| ERROR `X: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
+    //~| ERROR the size for value values of type
 }
 
 pub fn main() {
index 3e6c9cc4061e1cb8ff7a02bf94e5048404f4d410..e04aa3599e9b5805e47af228ffcdf65d3287d1c5 100644 (file)
 // Test `?Sized` types not allowed in fields (except the last one).
 
 struct S1<X: ?Sized> {
-    f1: X, //~ ERROR `X: std::marker::Sized` is not satisfied
+    f1: X,
+    //~^ ERROR the size for value values of type
     f2: isize,
 }
 struct S2<X: ?Sized> {
     f: isize,
-    g: X, //~ ERROR `X: std::marker::Sized` is not satisfied
+    g: X,
+    //~^ ERROR the size for value values of type
     h: isize,
 }
 struct S3 {
-    f: str, //~ ERROR `str: std::marker::Sized` is not satisfied
+    f: str,
+    //~^ ERROR the size for value values of type
     g: [usize]
 }
 struct S4 {
-    f: [u8], //~ ERROR `[u8]: std::marker::Sized` is not satisfied
+    f: [u8],
+    //~^ ERROR the size for value values of type
     g: usize
 }
 enum E<X: ?Sized> {
-    V1(X, isize), //~ERROR `X: std::marker::Sized` is not satisfied
+    V1(X, isize),
+    //~^ ERROR the size for value values of type
 }
 enum F<X: ?Sized> {
-    V2{f1: X, f: isize}, //~ERROR `X: std::marker::Sized` is not satisfied
+    V2{f1: X, f: isize},
+    //~^ ERROR the size for value values of type
 }
 
 pub fn main() {
index dec8699f46e3b3542b67f6f22377d0292b08f691..8ac9fe4c58787b1a54cd78cb0bd4acafd4dbf2e7 100644 (file)
@@ -14,28 +14,41 @@ trait T {}
 
 fn f1<W: ?Sized, X: ?Sized, Y: ?Sized, Z: ?Sized>(x: &X) {
     let _: W; // <-- this is OK, no bindings created, no initializer.
-    let _: (isize, (X, isize)); //~ERROR `X: std::marker::Sized` is not satisfie
-    let y: Y; //~ERROR `Y: std::marker::Sized` is not satisfied
-    let y: (isize, (Z, usize)); //~ERROR `Z: std::marker::Sized` is not satisfied
+    let _: (isize, (X, isize));
+    //~^ ERROR the size for value values of type
+    let y: Y;
+    //~^ ERROR the size for value values of type
+    let y: (isize, (Z, usize));
+    //~^ ERROR the size for value values of type
 }
 fn f2<X: ?Sized, Y: ?Sized>(x: &X) {
-    let y: X; //~ERROR `X: std::marker::Sized` is not satisfied
-    let y: (isize, (Y, isize)); //~ERROR `Y: std::marker::Sized` is not satisfied
+    let y: X;
+    //~^ ERROR the size for value values of type
+    let y: (isize, (Y, isize));
+    //~^ ERROR the size for value values of type
 }
 
 fn f3<X: ?Sized>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
-    let y: X = *x1; //~ERROR `X: std::marker::Sized` is not satisfied
-    let y = *x2; //~ERROR `X: std::marker::Sized` is not satisfied
-    let (y, z) = (*x3, 4); //~ERROR `X: std::marker::Sized` is not satisfied
+    let y: X = *x1;
+    //~^ ERROR the size for value values of type
+    let y = *x2;
+    //~^ ERROR the size for value values of type
+    let (y, z) = (*x3, 4);
+    //~^ ERROR the size for value values of type
 }
 fn f4<X: ?Sized + T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
-    let y: X = *x1;         //~ERROR `X: std::marker::Sized` is not satisfied
-    let y = *x2;            //~ERROR `X: std::marker::Sized` is not satisfied
-    let (y, z) = (*x3, 4); //~ERROR `X: std::marker::Sized` is not satisfied
+    let y: X = *x1;
+    //~^ ERROR the size for value values of type
+    let y = *x2;
+    //~^ ERROR the size for value values of type
+    let (y, z) = (*x3, 4);
+    //~^ ERROR the size for value values of type
 }
 
-fn g1<X: ?Sized>(x: X) {} //~ERROR `X: std::marker::Sized` is not satisfied
-fn g2<X: ?Sized + T>(x: X) {} //~ERROR `X: std::marker::Sized` is not satisfied
+fn g1<X: ?Sized>(x: X) {}
+//~^ ERROR the size for value values of type
+fn g2<X: ?Sized + T>(x: X) {}
+//~^ ERROR the size for value values of type
 
 pub fn main() {
 }
index 25868c594feb675326960008eff1724b43b84763..44d7df35680ce3bee8d5a6c7ea416d38514ce537 100644 (file)
@@ -20,7 +20,7 @@ trait T1<Z: T> {
 
 struct S3<Y: ?Sized>(Box<Y>);
 impl<X: ?Sized + T> T1<X> for S3<X> {
-    //~^ ERROR `X: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
 
 fn main() { }
index f59dca93bb90a72e292fdea49289cad5fc8b2671..f46a54504a0b5cd7c50835eb4dacf0165d0ad412 100644 (file)
@@ -17,7 +17,7 @@
 struct Bar<T:Eq+?Sized> { value: Box<T> }
 
 trait Foo {
-    fn bar(&self) where Bar<Self>: Copy;
+    fn bar(&self) where Self: Sized, Bar<Self>: Copy;
         //~^ ERROR E0277
         //
         // Here, Eq ought to be implemented.
index dadc755eb8c579a571932815bdeb1511e0d60246..30ba14c1bab3af49902b8133b503418a14552e8f 100644 (file)
@@ -68,17 +68,17 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
 // fn main::{{closure}}(_1: [closure@NodeId(22) d:&'19s D]) -> i32 {
 //     let mut _0: i32;
 //     ...
-//     let _2: &'15_0rs D;
+//     let _2: &'16_0rs D;
 //     ...
 //     let mut _3: i32;
 //     bb0: {
 //         StorageLive(_2);
-//         _2 = &'15_0rs (*(_1.0: &'19s D));
+//         _2 = &'16_0rs (*(_1.0: &'19s D));
 //         StorageLive(_3);
 //         _3 = ((*_2).0: i32);
 //         _0 = move _3;
 //         StorageDead(_3);
-//         EndRegion('15_0rs);
+//         EndRegion('16_0rs);
 //         StorageDead(_2);
 //         return;
 //     }
index 1426174b482b64af54495f376ab182502ea48096..6d6afa25ae30e4c788b424de4907026cb9db1493 100644 (file)
@@ -76,17 +76,17 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
 // fn main::{{closure}}(_1: [closure@NodeId(22) d:D]) -> i32 {
 //     let mut _0: i32;
 //     ...
-//     let _2: &'15_0rs D;
+//     let _2: &'16_0rs D;
 //     ...
 //     let mut _3: i32;
 //     bb0: {
 //         StorageLive(_2);
-//         _2 = &'15_0rs (_1.0: D);
+//         _2 = &'16_0rs (_1.0: D);
 //         StorageLive(_3);
 //         _3 = ((*_2).0: i32);
 //         _0 = move _3;
 //         StorageDead(_3);
-//         EndRegion('15_0rs);
+//         EndRegion('16_0rs);
 //         StorageDead(_2);
 //         drop(_1) -> [return: bb2, unwind: bb1];
 //     }
index e6cd535500055f1bac85ef56e3ef6f9f9c9eb7c2..c331276aade7756857cef58b821cff228c4b0222 100644 (file)
@@ -64,14 +64,14 @@ fn main() {
 //     bb0: {
 //         Validate(Acquire, [_1: &ReFree(DefId(0/1:11 ~ validate_1[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(50)], _2: &ReFree(DefId(0/1:11 ~ validate_1[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]);
 //         StorageLive(_3);
-//         Validate(Suspend(ReScope(Remainder(BlockRemainder { block: ItemLocalId(22), first_statement_index: 0 }))), [(*_2): i32]);
+//         Validate(Suspend(ReScope(Remainder(BlockRemainder { block: ItemLocalId(25), first_statement_index: 0 }))), [(*_2): i32]);
 //         _3 = &ReErased (*_2);
-//         Validate(Acquire, [(*_3): i32/ReScope(Remainder(BlockRemainder { block: ItemLocalId(22), first_statement_index: 0 })) (imm)]);
+//         Validate(Acquire, [(*_3): i32/ReScope(Remainder(BlockRemainder { block: ItemLocalId(25), first_statement_index: 0 })) (imm)]);
 //         StorageLive(_4);
 //         _4 = (*_3);
 //         _0 = move _4;
 //         StorageDead(_4);
-//         EndRegion(ReScope(Remainder(BlockRemainder { block: ItemLocalId(22), first_statement_index: 0 })));
+//         EndRegion(ReScope(Remainder(BlockRemainder { block: ItemLocalId(25), first_statement_index: 0 })));
 //         StorageDead(_3);
 //         return;
 //     }
index d8d83fb5b453707c69d2c8b46de919495d893358..b4d4479bab94a62eeed89817efd827950a8b72ce 100644 (file)
@@ -53,12 +53,12 @@ fn main() {
 //         StorageLive(_3);
 //         StorageLive(_4);
 //         StorageLive(_5);
-//         Validate(Suspend(ReScope(Node(ItemLocalId(9)))), [(*_2): i32]);
+//         Validate(Suspend(ReScope(Node(ItemLocalId(12)))), [(*_2): i32]);
 //         _5 = &ReErased mut (*_2);
-//         Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(9)))]);
+//         Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(12)))]);
 //         _4 = move _5 as *mut i32 (Misc);
 //         _3 = move _4;
-//         EndRegion(ReScope(Node(ItemLocalId(9))));
+//         EndRegion(ReScope(Node(ItemLocalId(12))));
 //         StorageDead(_4);
 //         StorageDead(_5);
 //         Validate(Release, [_0: bool, _3: *mut i32]);
index 3a330d8bee21b8c165a2c7b1e83f39069d75b2cb..05df16d21d85bcf5d65268fe57c0a696aa1c6758 100644 (file)
@@ -16,6 +16,6 @@ impl Foo {
     fn foo() {}
 
     #[stable(feature = "rust1", since = "1.0.0")]
-} //~ ERROR expected one of `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, or `unsafe`
+} //~ ERROR expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, or
 
 fn main() {}
index cd79fa8be7c6527062011514f4c46ca7089d5bb9..f30e20ad7dbdb3968194a357a6e399e7097d1e58 100644 (file)
@@ -14,6 +14,6 @@
 
 impl Foo {
     #[stable(feature = "rust1", since = "1.0.0")]
-} //~ ERROR expected one of `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, or `unsafe`
+} //~ ERROR expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, or
 
 fn main() {}
index fa6474717d3f0320afbcb2663fdc1d2b2580b9b6..34b96a59c2dde784b5f7b4bc39beb0cfa63f10e2 100644 (file)
 use std::ops::RangeToInclusive;
 
 fn return_range_to() -> RangeToInclusive<i32> {
-    return ...1; //~ERROR `...` syntax cannot be used in expressions
-                 //~^HELP  Use `..` if you need an exclusive range (a < b)
-                 //~^^HELP or `..=` if you need an inclusive range (a <= b)
+    return ...1; //~ERROR unexpected token: `...`
+                 //~^HELP  use `..` for an exclusive range
+                 //~^^HELP or `..=` for an inclusive range
 }
 
 pub fn main() {
-    let x = ...0;    //~ERROR `...` syntax cannot be used in expressions
-                     //~^HELP  Use `..` if you need an exclusive range (a < b)
-                     //~^^HELP or `..=` if you need an inclusive range (a <= b)
+    let x = ...0;    //~ERROR unexpected token: `...`
+                     //~^HELP  use `..` for an exclusive range
+                     //~^^HELP or `..=` for an inclusive range
 
-    let x = 5...5;   //~ERROR `...` syntax cannot be used in expressions
-                     //~^HELP  Use `..` if you need an exclusive range (a < b)
-                     //~^^HELP or `..=` if you need an inclusive range (a <= b)
+    let x = 5...5;   //~ERROR unexpected token: `...`
+                     //~^HELP  use `..` for an exclusive range
+                     //~^^HELP or `..=` for an inclusive range
 
-    for _ in 0...1 {} //~ERROR `...` syntax cannot be used in expressions
-                     //~^HELP  Use `..` if you need an exclusive range (a < b)
-                     //~^^HELP or `..=` if you need an inclusive range (a <= b)
+    for _ in 0...1 {} //~ERROR unexpected token: `...`
+                     //~^HELP  use `..` for an exclusive range
+                     //~^^HELP or `..=` for an inclusive range
 }
-
index 3b783aa79e281c2c00b001e1917d8007102d4c95..fbc6848f372f5666e9cd27c664941c24cbea6733 100644 (file)
@@ -15,4 +15,4 @@
 impl S {
     static fn f() {}
 }
-//~^^ ERROR expected one of `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`
+//~^^ ERROR expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`,
index fd356f4a81792cf277915e0b340e13f6bb0513af..9f94d5d41fda7d1375daa8ddadb013c3c55bedb0 100644 (file)
@@ -10,7 +10,7 @@
 
 macro_rules! bah {
     ($a:expr) => ($a)
-    //~^ ERROR expected one of `const`, `extern`, `fn`, `type`, or `unsafe`, found `2`
+    //~^ ERROR expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`, found `2`
 }
 
 trait bar {
index 6bc24e2081d19c9400f7eda02d0a273580debf1d..cce6b5c4cbf750cb0cc69fb70fcf47d62649e18d 100644 (file)
@@ -10,7 +10,7 @@
 
 trait Foo {
     pub const Foo: u32;
-    //~^ ERROR expected one of `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `pub`
+    //~^ ERROR expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found
 }
 
 fn main() {}
index 493ff087eaf9ec009c9eddaa9ff385707c0b3795..d6a4e5e021d3876704f01db5ebabd855581f0128 100644 (file)
@@ -10,7 +10,7 @@
 
 trait Foo {
     pub type Foo;
-    //~^ ERROR expected one of `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `pub`
+    //~^ ERROR expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found
 }
 
 fn main() {}
index c2ee3c31d885b87091affe6ee199bcb3f200b971..286cb4dbff7e183992d1925834307900bdb4e2af 100644 (file)
@@ -10,7 +10,7 @@
 
 trait Foo {
     pub fn foo();
-    //~^ ERROR expected one of `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `pub`
+    //~^ ERROR expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found
 }
 
 fn main() {}
index 3a848a31c4dd7671e712322a322d1132168f15fa..bbd81e790b838d5f303cd12d1c82354dbc0bc9b7 100644 (file)
@@ -124,6 +124,7 @@ fn iter_exprs(depth: usize, f: &mut FnMut(P<Expr>)) {
                 });
                 iter_exprs(depth - 1, &mut |e| g(
                         ExprKind::Closure(CaptureBy::Value,
+                                          IsAsync::NotAsync,
                                           Movability::Movable,
                                           decl.clone(),
                                           e,
diff --git a/src/test/run-pass/allow_irrefutable_let_patterns.rs b/src/test/run-pass/allow_irrefutable_let_patterns.rs
new file mode 100644 (file)
index 0000000..ea114b6
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(irrefutable_let_patterns)]
+
+// must-compile-successfully-irrefutable_let_patterns_with_gate
+#[allow(irrefutable_let_patterns)]
+fn main() {
+    if let _ = 5 {}
+
+    while let _ = 5 {
+        break;
+    }
+}
diff --git a/src/test/run-pass/async-await.rs b/src/test/run-pass/async-await.rs
new file mode 100644 (file)
index 0000000..817db4b
--- /dev/null
@@ -0,0 +1,152 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: --edition=2018
+
+#![feature(arbitrary_self_types, async_await, await_macro, futures_api, pin)]
+
+use std::boxed::PinBox;
+use std::mem::PinMut;
+use std::future::Future;
+use std::sync::{
+    Arc,
+    atomic::{self, AtomicUsize},
+};
+use std::task::{
+    Context, Poll, Wake,
+    Executor, TaskObj, SpawnObjError,
+    local_waker_from_nonlocal,
+};
+
+struct Counter {
+    wakes: AtomicUsize,
+}
+
+impl Wake for Counter {
+    fn wake(this: &Arc<Self>) {
+        this.wakes.fetch_add(1, atomic::Ordering::SeqCst);
+    }
+}
+
+struct NoopExecutor;
+impl Executor for NoopExecutor {
+    fn spawn_obj(&mut self, _: TaskObj) -> Result<(), SpawnObjError> {
+        Ok(())
+    }
+}
+
+struct WakeOnceThenComplete(bool);
+
+fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) }
+
+impl Future for WakeOnceThenComplete {
+    type Output = ();
+    fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<()> {
+        if self.0 {
+            Poll::Ready(())
+        } else {
+            cx.waker().wake();
+            self.0 = true;
+            Poll::Pending
+        }
+    }
+}
+
+fn async_block(x: u8) -> impl Future<Output = u8> {
+    async move {
+        await!(wake_and_yield_once());
+        x
+    }
+}
+
+fn async_nonmove_block(x: u8) -> impl Future<Output = u8> {
+    async move {
+        let future = async {
+            await!(wake_and_yield_once());
+            x
+        };
+        await!(future)
+    }
+}
+
+fn async_closure(x: u8) -> impl Future<Output = u8> {
+    (async move |x: u8| -> u8 {
+        await!(wake_and_yield_once());
+        x
+    })(x)
+}
+
+async fn async_fn(x: u8) -> u8 {
+    await!(wake_and_yield_once());
+    x
+}
+
+async fn async_fn_with_borrow(x: &u8) -> u8 {
+    await!(wake_and_yield_once());
+    *x
+}
+
+fn async_fn_with_internal_borrow(y: u8) -> impl Future<Output = u8> {
+    async move {
+        await!(async_fn_with_borrow(&y))
+    }
+}
+
+unsafe async fn unsafe_async_fn(x: u8) -> u8 {
+    await!(wake_and_yield_once());
+    x
+}
+
+struct Foo;
+
+trait Bar {
+    fn foo() {}
+}
+
+impl Foo {
+    async fn async_method(x: u8) -> u8 {
+        unsafe {
+            await!(unsafe_async_fn(x))
+        }
+    }
+}
+
+fn test_future_yields_once_then_returns<F, Fut>(f: F)
+where
+    F: FnOnce(u8) -> Fut,
+    Fut: Future<Output = u8>,
+{
+    let mut fut = PinBox::new(f(9));
+    let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) });
+    let waker = local_waker_from_nonlocal(counter.clone());
+    let executor = &mut NoopExecutor;
+    let cx = &mut Context::new(&waker, executor);
+
+    assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst));
+    assert_eq!(Poll::Pending, fut.as_pin_mut().poll(cx));
+    assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst));
+    assert_eq!(Poll::Ready(9), fut.as_pin_mut().poll(cx));
+}
+
+fn main() {
+    macro_rules! test {
+        ($($fn_name:ident,)*) => { $(
+            test_future_yields_once_then_returns($fn_name);
+        )* }
+    }
+
+    test! {
+        async_block,
+        async_nonmove_block,
+        async_closure,
+        async_fn,
+        async_fn_with_internal_borrow,
+    }
+}
index 19cd1cf3df717721c9bbfcdb85825b0699aa437a..862439e21f4f3737743737ac08e6ab66dcc36ade 100644 (file)
@@ -26,5 +26,5 @@ fn main() {
         std::intrinsics::type_name::<NT>(),
         // DST
         std::intrinsics::type_name::<DST>()
-    )}, ("[u8]", "str", "std::marker::Send", "NT", "DST"));
+    )}, ("[u8]", "str", "dyn std::marker::Send", "NT", "DST"));
 }
index 2dc4d775a9c45f17777f7cd00108af398068703f..4df46c0e2e1e7377cc514d93e22a8c11f5f14996 100644 (file)
@@ -32,8 +32,8 @@ pub fn noop_fold_impl_item() -> SmallVector<ImplItem> {
 struct S05_PolyTraitRef(S06_TraitRef);
 struct S06_TraitRef(S07_Path);
 struct S07_Path(Vec<S08_PathSegment>);
-struct S08_PathSegment(S09_PathParameters);
-struct S09_PathParameters(P<S10_ParenthesizedParameterData>);
+struct S08_PathSegment(S09_GenericArgs);
+struct S09_GenericArgs(P<S10_ParenthesizedParameterData>);
 struct S10_ParenthesizedParameterData(Option<P<S11_Ty>>);
 struct S11_Ty(P<S12_Expr>);
 struct S12_Expr(P<S13_Block>);
diff --git a/src/test/run-pass/issue-23435.rs b/src/test/run-pass/issue-23435.rs
deleted file mode 100644 (file)
index 9b72782..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that we do not ICE when a default method implementation has
-// requirements (in this case, `Self : Baz`) that do not hold for some
-// specific impl (in this case, `Foo : Bar`). This causes problems
-// only when building a vtable, because that goes along and
-// instantiates all the methods, even those that could not otherwise
-// be called.
-
-// pretty-expanded FIXME #23616
-
-struct Foo {
-    x: i32
-}
-
-trait Bar {
-    fn bar(&self) where Self : Baz { self.baz(); }
-}
-
-trait Baz {
-    fn baz(&self);
-}
-
-impl Bar for Foo {
-}
-
-fn main() {
-    let x: &Bar = &Foo { x: 22 };
-}
diff --git a/src/test/run-pass/issue-51655.rs b/src/test/run-pass/issue-51655.rs
new file mode 100644 (file)
index 0000000..b5b89ed
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(dead_code)]
+
+const PATH_DOT: &[u8] = &[b'.'];
+
+fn match_slice(element: &[u8]) {
+    match element {
+        &[] => {}
+        PATH_DOT => {}
+        _ => {}
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/allocator-submodule.rs b/src/test/ui/allocator-submodule.rs
new file mode 100644 (file)
index 0000000..39b6576
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Tests that it is possible to create a global allocator in a submodule, rather than in the crate
+// root.
+
+#![feature(alloc, allocator_api, global_allocator)]
+
+extern crate alloc;
+
+use std::{
+    alloc::{GlobalAlloc, Layout},
+    ptr,
+};
+
+struct MyAlloc;
+
+unsafe impl GlobalAlloc for MyAlloc {
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+        ptr::null_mut()
+    }
+
+    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {}
+}
+
+mod submod {
+    use super::MyAlloc;
+
+    #[global_allocator]
+    static MY_HEAP: MyAlloc = MyAlloc; //~ ERROR global_allocator
+}
+
+fn main() {}
diff --git a/src/test/ui/allocator-submodule.stderr b/src/test/ui/allocator-submodule.stderr
new file mode 100644 (file)
index 0000000..06e0d36
--- /dev/null
@@ -0,0 +1,8 @@
+error: `global_allocator` cannot be used in submodules
+  --> $DIR/allocator-submodule.rs:37:5
+   |
+LL |     static MY_HEAP: MyAlloc = MyAlloc; //~ ERROR global_allocator
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
index 82f527f8cca88f6d6a286a2b5f88e3a66dca4618..809d111d74e65e2ac921756ffcadb05b68e4fae8 100644 (file)
@@ -74,7 +74,7 @@ error[E0631]: type mismatch in closure arguments
 LL |     g1(|_: (), _: ()| {}); //~ ERROR type mismatch
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
-   |     expected signature of `for<'r> fn(&'r (), std::boxed::Box<for<'s> std::ops::Fn(&'s ()) + 'static>) -> _`
+   |     expected signature of `for<'r> fn(&'r (), std::boxed::Box<(dyn for<'s> std::ops::Fn(&'s ()) + 'static)>) -> _`
    |
 note: required by `g1`
   --> $DIR/anonymous-higher-ranked-lifetime.rs:33:1
@@ -102,7 +102,7 @@ error[E0631]: type mismatch in closure arguments
 LL |     g3(|_: (), _: ()| {}); //~ ERROR type mismatch
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
-   |     expected signature of `for<'s> fn(&'s (), std::boxed::Box<for<'r> std::ops::Fn(&'r ()) + 'static>) -> _`
+   |     expected signature of `for<'s> fn(&'s (), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _`
    |
 note: required by `g3`
   --> $DIR/anonymous-higher-ranked-lifetime.rs:35:1
@@ -130,7 +130,7 @@ error[E0631]: type mismatch in closure arguments
 LL |     h1(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch
    |     ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
    |     |
-   |     expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box<for<'t0> std::ops::Fn(&'t0 ()) + 'static>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _`
+   |     expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box<(dyn for<'t0> std::ops::Fn(&'t0 ()) + 'static)>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _`
    |
 note: required by `h1`
   --> $DIR/anonymous-higher-ranked-lifetime.rs:39:1
@@ -144,7 +144,7 @@ error[E0631]: type mismatch in closure arguments
 LL |     h2(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch
    |     ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
    |     |
-   |     expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box<for<'s> std::ops::Fn(&'s ()) + 'static>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _`
+   |     expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box<(dyn for<'s> std::ops::Fn(&'s ()) + 'static)>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _`
    |
 note: required by `h2`
   --> $DIR/anonymous-higher-ranked-lifetime.rs:40:1
index b3f9cbc587bac86053d5c1bd287267b6a86f5d5f..ec9e65fc4c62d3fb8717c1886e4a5d13bfdf4a76 100644 (file)
@@ -13,7 +13,7 @@ LL |     let x = Box::new(5usize) as Box<Foo>;
    |             ^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
    |
    = note: method `foo` has a non-standard `self` type
-   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<Foo>>` for `std::boxed::Box<usize>`
+   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<dyn Foo>>` for `std::boxed::Box<usize>`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/async-fn-multiple-lifetimes.rs b/src/test/ui/async-fn-multiple-lifetimes.rs
new file mode 100644 (file)
index 0000000..ce062de
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: --edition=2018
+
+#![feature(arbitrary_self_types, async_await, await_macro, futures_api, pin)]
+
+use std::ops::Add;
+
+async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}
+//~^ ERROR multiple different lifetimes used in arguments of `async fn`
+
+async fn multiple_hrtb_and_single_named_lifetime_ok<'c>(
+    _: impl for<'a> Add<&'a u8>,
+    _: impl for<'b> Add<&'b u8>,
+    _: &'c u8,
+) {}
+
+async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}
+//~^ ERROR multiple elided lifetimes used
+//~^^ ERROR missing lifetime specifier
+
+fn main() {}
diff --git a/src/test/ui/async-fn-multiple-lifetimes.stderr b/src/test/ui/async-fn-multiple-lifetimes.stderr
new file mode 100644 (file)
index 0000000..f203d9a
--- /dev/null
@@ -0,0 +1,32 @@
+error[E0709]: multiple different lifetimes used in arguments of `async fn`
+  --> $DIR/async-fn-multiple-lifetimes.rs:17:49
+   |
+LL | async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}
+   |                                               --^^^^^^^^^-- different lifetime here
+   |                                               |
+   |                                               first lifetime here
+   |
+   = help: `async fn` can only accept borrowed values with identical lifetimes
+
+error[E0707]: multiple elided lifetimes used in arguments of `async fn`
+  --> $DIR/async-fn-multiple-lifetimes.rs:26:39
+   |
+LL | async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}
+   |                                       -^^^^^^^- different lifetime here
+   |                                       |
+   |                                       first lifetime here
+   |
+   = help: consider giving these arguments named lifetimes
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/async-fn-multiple-lifetimes.rs:26:39
+   |
+LL | async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}
+   |                                       ^ expected lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_` or `_`
+
+error: aborting due to 3 previous errors
+
+Some errors occurred: E0106, E0707, E0709.
+For more information about an error, try `rustc --explain E0106`.
index 1b370567ed10c7d55f1085b6a792f290f2be8571..601f05b499c75c2a46f7e73083db8cb914338dd8 100644 (file)
@@ -7,7 +7,7 @@ LL |     //~^ value moved here
 LL |     let _y = a.y; //~ ERROR use of moved
    |              ^^^ value used here after move
    |
-   = note: move occurs because `a.y` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
+   = note: move occurs because `a.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
 
 error[E0382]: use of moved value: `a.y`
   --> $DIR/borrowck-box-insensitivity.rs:108:14
@@ -18,7 +18,7 @@ LL |     //~^ value moved here
 LL |     let _y = a.y; //~ ERROR use of collaterally moved
    |              ^^^ value used here after move
    |
-   = note: move occurs because `a.y` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
+   = note: move occurs because `a.x.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
 
 error: aborting due to 2 previous errors
 
index 29481dbe522110c2b724e896cce35065673fed52..2a94e05016d4edff759287c8ed80717eb095dfed 100644 (file)
@@ -20,7 +20,7 @@ pub fn main(){
         //~| ERROR use of moved value: `(maybe as std::prelude::v1::Some).0` (Ast) [E0382]
         //~| ERROR use of moved value: `maybe` (Mir) [E0382]
         //~| ERROR use of moved value: `maybe` (Mir) [E0382]
-        //~| ERROR use of moved value: `maybe.0` (Mir) [E0382]
+        //~| ERROR use of moved value (Mir) [E0382]
         //~| ERROR borrow of moved value: `maybe` (Mir) [E0382]
     }
 }
index e6eb3739d8c6fd3a624343944bbb24ea900b1a91..bd5d2a46fd8c751ab127cfa7f19e146033231dfe 100644 (file)
@@ -26,7 +26,7 @@ LL |           if let Some(thing) = maybe {
 LL | |         }
    | |_________^ value used here after move
    |
-   = note: move occurs because `maybe` has type `std::option::Option<std::vec::Vec<bool>>`, which does not implement the `Copy` trait
+   = note: move occurs because value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
 
 error[E0382]: borrow of moved value: `maybe` (Mir)
   --> $DIR/issue-41962.rs:17:9
@@ -38,7 +38,7 @@ LL |           if let Some(thing) = maybe {
 LL | |         }
    | |_________^ value borrowed here after move
    |
-   = note: move occurs because `maybe` has type `std::option::Option<std::vec::Vec<bool>>`, which does not implement the `Copy` trait
+   = note: move occurs because value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
 
 error[E0382]: use of moved value: `maybe` (Mir)
   --> $DIR/issue-41962.rs:17:16
@@ -49,15 +49,15 @@ LL |         if let Some(thing) = maybe {
    |                |    value moved here
    |                value used here after move
    |
-   = note: move occurs because `maybe` has type `std::option::Option<std::vec::Vec<bool>>`, which does not implement the `Copy` trait
+   = note: move occurs because value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
 
-error[E0382]: use of moved value: `maybe.0` (Mir)
+error[E0382]: use of moved value (Mir)
   --> $DIR/issue-41962.rs:17:21
    |
 LL |         if let Some(thing) = maybe {
    |                     ^^^^^ value moved here in previous iteration of loop
    |
-   = note: move occurs because `maybe.0` has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
+   = note: move occurs because value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/borrowck/issue-51415.nll.stderr b/src/test/ui/borrowck/issue-51415.nll.stderr
new file mode 100644 (file)
index 0000000..79454b6
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/issue-51415.rs:16:47
+   |
+LL |     let opt = a.iter().enumerate().find(|(_, &s)| {
+   |                                               ^ cannot move out of borrowed content
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.
diff --git a/src/test/ui/borrowck/issue-51415.rs b/src/test/ui/borrowck/issue-51415.rs
new file mode 100644 (file)
index 0000000..9067a50
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Regression test for #51415: match default bindings were failing to
+// see the "move out" implied by `&s` below.
+
+fn main() {
+    let a = vec![String::from("a")];
+    let opt = a.iter().enumerate().find(|(_, &s)| {
+        //~^ ERROR cannot move out
+        *s == String::from("d")
+    }).map(|(i, _)| i);
+    println!("{:?}", opt);
+}
diff --git a/src/test/ui/borrowck/issue-51415.stderr b/src/test/ui/borrowck/issue-51415.stderr
new file mode 100644 (file)
index 0000000..b4b0bc7
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/issue-51415.rs:16:46
+   |
+LL |     let opt = a.iter().enumerate().find(|(_, &s)| {
+   |                                              ^-
+   |                                              ||
+   |                                              |hint: to prevent move, use `ref s` or `ref mut s`
+   |                                              cannot move out of borrowed content
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.
index 67c33740f19695d772211396bb5b6ddbc23150ba..1e871d472842097a4df8383d24716837ed788c2b 100644 (file)
@@ -1,4 +1,4 @@
-error[E0620]: cast to unsized type: `&{integer}` as `std::marker::Send`
+error[E0620]: cast to unsized type: `&{integer}` as `dyn std::marker::Send`
   --> $DIR/cast-to-unsized-trait-object-suggestion.rs:12:5
    |
 LL |     &1 as Send; //~ ERROR cast to unsized
@@ -6,7 +6,7 @@ LL |     &1 as Send; //~ ERROR cast to unsized
    |           |
    |           help: try casting to a reference instead: `&Send`
 
-error[E0620]: cast to unsized type: `std::boxed::Box<{integer}>` as `std::marker::Send`
+error[E0620]: cast to unsized type: `std::boxed::Box<{integer}>` as `dyn std::marker::Send`
   --> $DIR/cast-to-unsized-trait-object-suggestion.rs:13:5
    |
 LL |     Box::new(1) as Send; //~ ERROR cast to unsized
diff --git a/src/test/ui/chalkify/lower_struct.rs b/src/test/ui/chalkify/lower_struct.rs
new file mode 100644 (file)
index 0000000..9287555
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(rustc_attrs)]
+
+#[rustc_dump_program_clauses] //~ ERROR program clause dump
+struct Foo<T> where Box<T>: Clone {
+    _x: std::marker::PhantomData<T>,
+}
+
+fn main() { }
diff --git a/src/test/ui/chalkify/lower_struct.stderr b/src/test/ui/chalkify/lower_struct.stderr
new file mode 100644 (file)
index 0000000..d6cc9c8
--- /dev/null
@@ -0,0 +1,12 @@
+error: program clause dump
+  --> $DIR/lower_struct.rs:13:1
+   |
+LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: FromEnv(T: std::marker::Sized) :- FromEnv(Foo<T>).
+   = note: FromEnv(std::boxed::Box<T>: std::clone::Clone) :- FromEnv(Foo<T>).
+   = note: WellFormed(Foo<T>) :- Implemented(T: std::marker::Sized), Implemented(std::boxed::Box<T>: std::clone::Clone).
+
+error: aborting due to previous error
+
index 7f6f503c6ff7235fbae3a441abbae71d45f8c6fb..ea275d647fa7c143fb66a355d8853c1355906656 100644 (file)
@@ -4,10 +4,10 @@ error: program clause dump
 LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: FromEnv(<F as std::ops::FnOnce<(&'a (u8, u16),)>>::Output == &'a u8) :- FromEnv(Self: Foo<F>).
    = note: FromEnv(F: std::marker::Sized) :- FromEnv(Self: Foo<F>).
    = note: FromEnv(F: std::ops::Fn<(&'a (u8, u16),)>) :- FromEnv(Self: Foo<F>).
    = note: Implemented(Self: Foo<F>) :- FromEnv(Self: Foo<F>).
+   = note: ProjectionEq(<F as std::ops::FnOnce<(&'a (u8, u16),)>>::Output == &'a u8) :- FromEnv(Self: Foo<F>).
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closure-array-break-length.rs b/src/test/ui/closure-array-break-length.rs
new file mode 100644 (file)
index 0000000..2e99921
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    |_: [_; continue]| {}; //~ ERROR: `continue` outside of loop
+
+    while |_: [_; continue]| {} {} //~ ERROR: `break` or `continue` with no label
+
+    while |_: [_; break]| {} {} //~ ERROR: `break` or `continue` with no label
+}
diff --git a/src/test/ui/closure-array-break-length.stderr b/src/test/ui/closure-array-break-length.stderr
new file mode 100644 (file)
index 0000000..1391539
--- /dev/null
@@ -0,0 +1,22 @@
+error[E0268]: `continue` outside of loop
+  --> $DIR/closure-array-break-length.rs:12:13
+   |
+LL |     |_: [_; continue]| {}; //~ ERROR: `continue` outside of loop
+   |             ^^^^^^^^ cannot break outside of a loop
+
+error[E0590]: `break` or `continue` with no label in the condition of a `while` loop
+  --> $DIR/closure-array-break-length.rs:14:19
+   |
+LL |     while |_: [_; continue]| {} {} //~ ERROR: `break` or `continue` with no label
+   |                   ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop
+
+error[E0590]: `break` or `continue` with no label in the condition of a `while` loop
+  --> $DIR/closure-array-break-length.rs:16:19
+   |
+LL |     while |_: [_; break]| {} {} //~ ERROR: `break` or `continue` with no label
+   |                   ^^^^^ unlabeled `break` in the condition of a `while` loop
+
+error: aborting due to 3 previous errors
+
+Some errors occurred: E0268, E0590.
+For more information about an error, try `rustc --explain E0268`.
index b9b03c9b9ec6224219220fbbfeab29cab562bf68..4271382ed5b22e06e40ee85af03714854b148513 100644 (file)
@@ -1,8 +1,11 @@
-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 `路濫狼á́́`
+error[E0703]: invalid ABI: found `路濫狼á́́`
   --> $DIR/unicode.rs:11:8
    |
 LL | extern "路濫狼á́́" fn foo() {} //~ ERROR invalid ABI
-   |        ^^^^^^^^^
+   |        ^^^^^^^^^ invalid ABI
+   |
+   = help: valid ABIs: cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0703`.
index c6ce34b60ca770d11733b2fd88914429ab352b87..c0a367604c374be88f353433d4c2b54b5b47420d 100644 (file)
 use std::fmt::Debug;
 
 const CONST_0: Debug+Sync = *(&0 as &(Debug+Sync));
-//~^ ERROR `std::fmt::Debug + std::marker::Sync + 'static: std::marker::Sized` is not satisfied
+//~^ ERROR the size for value values of type
 
 const CONST_FOO: str = *"foo";
-//~^ ERROR `str: std::marker::Sized` is not satisfied
+//~^ ERROR the size for value values of type
 
 static STATIC_1: Debug+Sync = *(&1 as &(Debug+Sync));
-//~^ ERROR `std::fmt::Debug + std::marker::Sync + 'static: std::marker::Sized` is not satisfied
+//~^ ERROR the size for value values of type
 
 static STATIC_BAR: str = *"bar";
-//~^ ERROR `str: std::marker::Sized` is not satisfied
+//~^ ERROR the size for value values of type
 
 fn main() {
     println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR);
index 0bbb5debbba69c02be8cf109c2e2c26242e4d3f0..d6fc5391ba83111c1f1c3f55461d65b3e99951dc 100644 (file)
@@ -1,37 +1,41 @@
-error[E0277]: the trait bound `std::fmt::Debug + std::marker::Sync + 'static: std::marker::Sized` is not satisfied
+error[E0277]: the size for value values of type `(dyn std::fmt::Debug + std::marker::Sync + 'static)` cannot be known at compilation time
   --> $DIR/const-unsized.rs:13:29
    |
 LL | const CONST_0: Debug+Sync = *(&0 as &(Debug+Sync));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^ `std::fmt::Debug + std::marker::Sync + 'static` does not have a constant size known at compile-time
+   |                             ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = help: the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + std::marker::Sync + 'static`
+   = help: the trait `std::marker::Sized` is not implemented for `(dyn std::fmt::Debug + std::marker::Sync + 'static)`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: constant expressions must have a statically known size
 
-error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
+error[E0277]: the size for value values of type `str` cannot be known at compilation time
   --> $DIR/const-unsized.rs:16:24
    |
 LL | const CONST_FOO: str = *"foo";
-   |                        ^^^^^^ `str` does not have a constant size known at compile-time
+   |                        ^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `str`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: constant expressions must have a statically known size
 
-error[E0277]: the trait bound `std::fmt::Debug + std::marker::Sync + 'static: std::marker::Sized` is not satisfied
+error[E0277]: the size for value values of type `(dyn std::fmt::Debug + std::marker::Sync + 'static)` cannot be known at compilation time
   --> $DIR/const-unsized.rs:19:31
    |
 LL | static STATIC_1: Debug+Sync = *(&1 as &(Debug+Sync));
-   |                               ^^^^^^^^^^^^^^^^^^^^^^ `std::fmt::Debug + std::marker::Sync + 'static` does not have a constant size known at compile-time
+   |                               ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = help: the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + std::marker::Sync + 'static`
+   = help: the trait `std::marker::Sized` is not implemented for `(dyn std::fmt::Debug + std::marker::Sync + 'static)`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: constant expressions must have a statically known size
 
-error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
+error[E0277]: the size for value values of type `str` cannot be known at compilation time
   --> $DIR/const-unsized.rs:22:26
    |
 LL | static STATIC_BAR: str = *"bar";
-   |                          ^^^^^^ `str` does not have a constant size known at compile-time
+   |                          ^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `str`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: constant expressions must have a statically known size
 
 error: aborting due to 4 previous errors
index 169a12ef92e987c1f8b6ad24aae7026ee01f52dd..33792d4f5b3fa4cb62efff4fe2ae71a42a6b3469 100644 (file)
@@ -92,7 +92,7 @@ error[E0223]: ambiguous associated type
 LL | type G = 'static + (Send)::AssocTy;
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^ ambiguous associated type
    |
-   = note: specify the type using the syntax `<std::marker::Send + 'static as Trait>::AssocTy`
+   = note: specify the type using the syntax `<(dyn std::marker::Send + 'static) as Trait>::AssocTy`
 
 error[E0223]: ambiguous associated type
   --> $DIR/bad-assoc-ty.rs:43:10
@@ -100,7 +100,7 @@ error[E0223]: ambiguous associated type
 LL | type H = Fn(u8) -> (u8)::Output;
    |          ^^^^^^^^^^^^^^^^^^^^^^ ambiguous associated type
    |
-   = note: specify the type using the syntax `<std::ops::Fn(u8) -> u8 + 'static as Trait>::Output`
+   = note: specify the type using the syntax `<(dyn std::ops::Fn(u8) -> u8 + 'static) as Trait>::Output`
 
 error: aborting due to 15 previous errors
 
index a3433939573a1570e469470f8605d25896298fb6..d3ce2cf12f2969c6d0bad31d4cfeded6b3b5cf39 100644 (file)
@@ -38,11 +38,11 @@ LL |       L = M; //~ ERROR missing
 LL | |     Z = { 2 + 3 }; //~ ERROR expected one of
    | |____^ missing `fn`, `type`, or `const`
 
-error: expected one of `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `;`
+error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `;`
   --> $DIR/issue-40006.rs:23:18
    |
 LL |     Z = { 2 + 3 }; //~ ERROR expected one of
-   |                  ^ expected one of `const`, `extern`, `fn`, `type`, `unsafe`, or `}` here
+   |                  ^ expected one of 7 possible tokens here
 
 error: expected one of `!` or `::`, found `(`
   --> $DIR/issue-40006.rs:24:9
index 29c5ea41f1fac2f51930980c1f92a6917ade560a..02dc8c8795675c34313c00a516449075e0eb0a20 100644 (file)
@@ -25,7 +25,7 @@ pub fn check_async() {
     r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async`
     r#async = consumes_async_raw!(r#async); // OK
 
-    if passes_ident!(async) == 1 {} //~ ERROR expected expression, found reserved keyword `async`
+    if passes_ident!(async) == 1 {}
     if passes_ident!(r#async) == 1 {} // OK
     module::async(); //~ ERROR expected identifier, found reserved keyword `async`
     module::r#async(); // OK
index 0b3ca57bfab151cfffa55ac53b07a2c5a75f6fd2..ceab5ea730ea88ee41ec45245fad64da2b84ecdb 100644 (file)
@@ -22,11 +22,11 @@ error: no rules expected the token `async`
 LL |     r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async`
    |                                   ^^^^^
 
-error: expected expression, found reserved keyword `async`
-  --> $DIR/edition-keywords-2018-2015-parsing.rs:28:22
+error: expected one of `move`, `|`, or `||`, found `<eof>`
+  --> <passes_ident macros>:1:22
    |
-LL |     if passes_ident!(async) == 1 {} //~ ERROR expected expression, found reserved keyword `async`
-   |                      ^^^^^ expected expression
+LL | ( $ i : ident ) => ( $ i )
+   |                      ^^^ expected one of `move`, `|`, or `||` here
 
 error: aborting due to 5 previous errors
 
index a94808eb2246cb97236a8d64fdeafdce2a1de0c2..f9b4d0e18c14b3e9c6d954a43287e3af3d3ab113 100644 (file)
@@ -25,7 +25,7 @@ pub fn check_async() {
     r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async`
     r#async = consumes_async_raw!(r#async); // OK
 
-    if passes_ident!(async) == 1 {} //~ ERROR expected expression, found reserved keyword `async`
+    if passes_ident!(async) == 1 {}
     if passes_ident!(r#async) == 1 {} // OK
     module::async(); //~ ERROR expected identifier, found reserved keyword `async`
     module::r#async(); // OK
index 1b18d8a39beb44f8ea7cfb136fcd194ad25a03a0..e48aac0a2bba9397512535d3ebce84ead33506e2 100644 (file)
@@ -22,11 +22,11 @@ error: no rules expected the token `async`
 LL |     r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async`
    |                                   ^^^^^
 
-error: expected expression, found reserved keyword `async`
-  --> $DIR/edition-keywords-2018-2018-parsing.rs:28:22
+error: expected one of `move`, `|`, or `||`, found `<eof>`
+  --> <passes_ident macros>:1:22
    |
-LL |     if passes_ident!(async) == 1 {} //~ ERROR expected expression, found reserved keyword `async`
-   |                      ^^^^^ expected expression
+LL | ( $ i : ident ) => ( $ i )
+   |                      ^^^ expected one of `move`, `|`, or `||` here
 
 error: aborting due to 5 previous errors
 
index c74485781c123db6f0b12848b97881aeac3a3064..2fac6080f496a263edec158d5909b59270fd88bc 100644 (file)
@@ -12,11 +12,11 @@ LL |     let trait_obj: &SomeTrait = SomeTrait;
    |
    = note: method `foo` has no receiver
 
-error[E0033]: type `&SomeTrait` cannot be dereferenced
+error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
   --> $DIR/E0033-teach.rs:23:9
    |
 LL |     let &invalid = trait_obj;
-   |         ^^^^^^^^ type `&SomeTrait` cannot be dereferenced
+   |         ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced
    |
    = note: This error indicates that a pointer to a trait type cannot be implicitly dereferenced by a pattern. Every trait defines a type, but because the size of trait implementors isn't fixed, this type has no compile-time size. Therefore, all accesses to trait types must be through pointers. If you encounter this error you should try to avoid dereferencing the pointer.
            
index a1e72d6f6695557da20d0500a1ee16393a35d3a4..5d789566beb066e9f0da6536ad9884840fe0123e 100644 (file)
@@ -12,11 +12,11 @@ LL |     let trait_obj: &SomeTrait = SomeTrait;
    |
    = note: method `foo` has no receiver
 
-error[E0033]: type `&SomeTrait` cannot be dereferenced
+error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
   --> $DIR/E0033.rs:21:9
    |
 LL |     let &invalid = trait_obj;
-   |         ^^^^^^^^ type `&SomeTrait` cannot be dereferenced
+   |         ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced
 
 error: aborting due to 3 previous errors
 
index 10e06ee6d025a4f5169d6b3e9b0b5342ba7ed25e..7f5b78684fbc18a9011b7cd6585532a47594279b 100644 (file)
@@ -2,7 +2,7 @@ error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/E0110.rs:11:14
    |
 LL | type X = u32<'static>; //~ ERROR E0110
-   |              ^^^^^^^ lifetime parameter not allowed on this type
+   |              ^^^^^^^ lifetime parameter not allowed
 
 error: aborting due to previous error
 
index ba9355763f67aca3816b635992ddfffd4f0309e2..46bc872746cc32492d16ccd787bf2afdd5ae6f91 100644 (file)
@@ -1,8 +1,8 @@
-error[E0131]: `main` function is not allowed to have type parameters
+error[E0131]: `main` function is not allowed to have generic parameters
   --> $DIR/E0131.rs:11:8
    |
 LL | fn main<T>() {
-   |        ^^^ `main` cannot have type parameters
+   |        ^^^ `main` cannot have generic parameters
 
 error: aborting due to previous error
 
index 4d1c50002a39c1f6e6b53dbdcd10d1a03fb00329..313aa1f706e9320b186743ce46dcd6d7d5db648d 100644 (file)
@@ -24,5 +24,5 @@ fn is_send<T: Send>() { }
 
 fn main() {
     is_send::<Foo>();
-    //~^ ERROR the trait bound `*const u8: std::marker::Send` is not satisfied in `Foo`
+    //~^ ERROR `*const u8` cannot be sent between threads safely
 }
index bbe04cfc6e16d9ceb708e684a32915ddd719f400..32776f028b4cec69fc7657c3c899c625b3fbb807 100644 (file)
@@ -1,4 +1,4 @@
-error[E0277]: the trait bound `*const u8: std::marker::Send` is not satisfied in `Foo`
+error[E0277]: `*const u8` cannot be sent between threads safely
   --> $DIR/E0277-2.rs:26:5
    |
 LL |     is_send::<Foo>();
index b29e435701507c931552e16e8145f3094e6bbcc4..95f10e7206f92ec7816fbe2d564f9f4d88bd7333 100644 (file)
@@ -21,7 +21,7 @@ fn some_func<T: Foo>(foo: T) {
 }
 
 fn f(p: Path) { }
-//~^ ERROR the trait bound `[u8]: std::marker::Sized` is not satisfied in `std::path::Path`
+//~^ ERROR the size for value values of type
 
 fn main() {
     some_func(5i32);
index 477128d7d9f08c0ef47c864acf86a6a57e47aa7e..ca5b0d2b987d6ac2c06c43c844ba070acd334c71 100644 (file)
@@ -1,10 +1,11 @@
-error[E0277]: the trait bound `[u8]: std::marker::Sized` is not satisfied in `std::path::Path`
+error[E0277]: the size for value values of type `[u8]` cannot be known at compilation time
   --> $DIR/E0277.rs:23:6
    |
 LL | fn f(p: Path) { }
-   |      ^ `[u8]` does not have a constant size known at compile-time
+   |      ^ doesn't have a size known at compile-time
    |
    = help: within `std::path::Path`, the trait `std::marker::Sized` is not implemented for `[u8]`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: required because it appears within the type `std::path::Path`
    = note: all local variables must have a statically known size
 
index 0cb8af9929418245cd5f0f91e58bb9e3658adc38..0777c44058fe81e3cf682c9448413d6789dfff45 100644 (file)
@@ -1,4 +1,4 @@
-error[E0558]: export_name attribute has invalid format
+error[E0558]: `export_name` attribute has invalid format
   --> $DIR/E0558.rs:11:1
    |
 LL | #[export_name]
diff --git a/src/test/ui/error-codes/E0648.rs b/src/test/ui/error-codes/E0648.rs
new file mode 100644 (file)
index 0000000..d3eac60
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[export_name="\0foo"] //~ ERROR E0648
+pub fn bar() {}
+
+fn main() {}
diff --git a/src/test/ui/error-codes/E0648.stderr b/src/test/ui/error-codes/E0648.stderr
new file mode 100644 (file)
index 0000000..1e11705
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0648]: `export_name` may not contain null characters
+  --> $DIR/E0648.rs:11:1
+   |
+LL | #[export_name="/0foo"] //~ ERROR E0648
+   | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0648`.
index c23aa40ee3790d54a055fb2e5177f454bcd5eac6..05a4b8b3544f5dc1932017abf18d767305525af7 100644 (file)
@@ -19,7 +19,7 @@ fn free_fn_capture_hrtb_in_impl_trait()
     -> Box<for<'a> Id<impl Lt<'a>>>
         //~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level [E0657]
 {
-    ()
+    () //~ ERROR mismatched types
 }
 
 struct Foo;
@@ -28,7 +28,7 @@ fn impl_fn_capture_hrtb_in_impl_trait()
         -> Box<for<'a> Id<impl Lt<'a>>>
             //~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level
     {
-        ()
+        () //~ ERROR mismatched types
     }
 }
 
index 737ae3a163ac20c219e2ed3db3929f9a4f184aae..fb7f88d5ca977e78adf9c3ef545d78fddbb6670e 100644 (file)
@@ -10,6 +10,25 @@ error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl le
 LL |         -> Box<for<'a> Id<impl Lt<'a>>>
    |                                   ^^
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/E0657.rs:22:5
+   |
+LL |     () //~ ERROR mismatched types
+   |     ^^ expected struct `std::boxed::Box`, found ()
+   |
+   = note: expected type `std::boxed::Box<(dyn Id<_> + 'static)>`
+              found type `()`
+
+error[E0308]: mismatched types
+  --> $DIR/E0657.rs:31:9
+   |
+LL |         () //~ ERROR mismatched types
+   |         ^^ expected struct `std::boxed::Box`, found ()
+   |
+   = note: expected type `std::boxed::Box<(dyn Id<_> + 'static)>`
+              found type `()`
+
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0657`.
+Some errors occurred: E0308, E0657.
+For more information about an error, try `rustc --explain E0308`.
index cf1dcfcb8ade39447de0a0951a0f477d469251b4..778a4cf1fa01f16de791a08cea0222409da44a71 100644 (file)
@@ -52,7 +52,7 @@ error[E0607]: cannot cast thin pointer `*const i32` to fat pointer `*const [i32]
 LL |     q as *const [i32]; //~ ERROR cannot cast
    |     ^^^^^^^^^^^^^^^^^
 
-error[E0606]: casting `usize` as `*mut Trait + 'static` is invalid
+error[E0606]: casting `usize` as `*mut (dyn Trait + 'static)` is invalid
   --> $DIR/fat-ptr-cast.rs:32:37
    |
 LL |     let t: *mut (Trait + 'static) = 0 as *mut _; //~ ERROR casting
diff --git a/src/test/ui/feature-gate-async-await-2015-edition.rs b/src/test/ui/feature-gate-async-await-2015-edition.rs
new file mode 100644 (file)
index 0000000..b1dd6a7
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: --edition=2015
+
+#![feature(futures_api)]
+
+async fn foo() {} //~ ERROR async fn is unstable
+
+fn main() {
+    let _ = async {}; //~ ERROR cannot find struct, variant or union type `async`
+    let _ = async || {}; //~ ERROR cannot find value `async` in this scope
+}
diff --git a/src/test/ui/feature-gate-async-await-2015-edition.stderr b/src/test/ui/feature-gate-async-await-2015-edition.stderr
new file mode 100644 (file)
index 0000000..3db90a4
--- /dev/null
@@ -0,0 +1,24 @@
+error[E0422]: cannot find struct, variant or union type `async` in this scope
+  --> $DIR/feature-gate-async-await-2015-edition.rs:18:13
+   |
+LL |     let _ = async {}; //~ ERROR cannot find struct, variant or union type `async`
+   |             ^^^^^ not found in this scope
+
+error[E0425]: cannot find value `async` in this scope
+  --> $DIR/feature-gate-async-await-2015-edition.rs:19:13
+   |
+LL |     let _ = async || {}; //~ ERROR cannot find value `async` in this scope
+   |             ^^^^^ not found in this scope
+
+error[E0658]: async fn is unstable (see issue #50547)
+  --> $DIR/feature-gate-async-await-2015-edition.rs:15:1
+   |
+LL | async fn foo() {} //~ ERROR async fn is unstable
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(async_await)] to the crate attributes to enable
+
+error: aborting due to 3 previous errors
+
+Some errors occurred: E0422, E0425, E0658.
+For more information about an error, try `rustc --explain E0422`.
diff --git a/src/test/ui/feature-gate-async-await.rs b/src/test/ui/feature-gate-async-await.rs
new file mode 100644 (file)
index 0000000..971b75c
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: --edition=2018
+#![feature(futures_api)]
+
+async fn foo() {} //~ ERROR async fn is unstable
+
+fn main() {
+    let _ = async {}; //~ ERROR async blocks are unstable
+    let _ = async || {}; //~ ERROR async closures are unstable
+}
diff --git a/src/test/ui/feature-gate-async-await.stderr b/src/test/ui/feature-gate-async-await.stderr
new file mode 100644 (file)
index 0000000..fdee6e2
--- /dev/null
@@ -0,0 +1,27 @@
+error[E0658]: async fn is unstable (see issue #50547)
+  --> $DIR/feature-gate-async-await.rs:14:1
+   |
+LL | async fn foo() {} //~ ERROR async fn is unstable
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(async_await)] to the crate attributes to enable
+
+error[E0658]: async blocks are unstable (see issue #50547)
+  --> $DIR/feature-gate-async-await.rs:17:13
+   |
+LL |     let _ = async {}; //~ ERROR async blocks are unstable
+   |             ^^^^^^^^
+   |
+   = help: add #![feature(async_await)] to the crate attributes to enable
+
+error[E0658]: async closures are unstable (see issue #50547)
+  --> $DIR/feature-gate-async-await.rs:18:13
+   |
+LL |     let _ = async || {}; //~ ERROR async closures are unstable
+   |             ^^^^^^^^^^^
+   |
+   = help: add #![feature(async_await)] to the crate attributes to enable
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
index 9c2c80600b8c8f0f80204850a963298e5a62e7fd..19a6a8637957eb91de7eb2e4c15ea9d9ab5ae67d 100644 (file)
@@ -87,38 +87,41 @@ LL | | }
    = help: see issue #48214
    = help: add #![feature(trivial_bounds)] to the crate attributes to enable
 
-error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
+error[E0277]: the size for value values of type `str` cannot be known at compilation time
   --> $DIR/feature-gate-trivial_bounds.rs:62:1
    |
 LL | struct TwoStrs(str, str) where str: Sized; //~ ERROR
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `str` does not have a constant size known at compile-time
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `str`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = help: see issue #48214
    = help: add #![feature(trivial_bounds)] to the crate attributes to enable
 
-error[E0277]: the trait bound `A + 'static: std::marker::Sized` is not satisfied in `Dst<A + 'static>`
+error[E0277]: the size for value values of type `(dyn A + 'static)` cannot be known at compilation time
   --> $DIR/feature-gate-trivial_bounds.rs:65:1
    |
 LL | / fn unsized_local() where Dst<A>: Sized { //~ ERROR
 LL | |     let x: Dst<A> = *(Box::new(Dst { x: 1 }) as Box<Dst<A>>);
 LL | | }
-   | |_^ `A + 'static` does not have a constant size known at compile-time
+   | |_^ doesn't have a size known at compile-time
    |
-   = help: within `Dst<A + 'static>`, the trait `std::marker::Sized` is not implemented for `A + 'static`
-   = note: required because it appears within the type `Dst<A + 'static>`
+   = help: within `Dst<(dyn A + 'static)>`, the trait `std::marker::Sized` is not implemented for `(dyn A + 'static)`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
+   = note: required because it appears within the type `Dst<(dyn A + 'static)>`
    = help: see issue #48214
    = help: add #![feature(trivial_bounds)] to the crate attributes to enable
 
-error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
+error[E0277]: the size for value values of type `str` cannot be known at compilation time
   --> $DIR/feature-gate-trivial_bounds.rs:69:1
    |
 LL | / fn return_str() -> str where str: Sized { //~ ERROR
 LL | |     *"Sized".to_string().into_boxed_str()
 LL | | }
-   | |_^ `str` does not have a constant size known at compile-time
+   | |_^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `str`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = help: see issue #48214
    = help: add #![feature(trivial_bounds)] to the crate attributes to enable
 
index 807b499155b855955c11df69b719a14717e25f6e..0d9239d72276e899c6424bd26de45e4666faf111 100644 (file)
@@ -1,11 +1,11 @@
-error[E0277]: `*mut std::ops::Fn() + 'static` cannot be shared between threads safely
+error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
   --> $DIR/send-sync.rs:18:5
    |
 LL |     send(format_args!("{:?}", c)); //~ ERROR E0277
-   |     ^^^^ `*mut std::ops::Fn() + 'static` cannot be shared between threads safely
+   |     ^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
    |
-   = help: within `[std::fmt::ArgumentV1<'_>]`, the trait `std::marker::Sync` is not implemented for `*mut std::ops::Fn() + 'static`
-   = note: required because it appears within the type `std::marker::PhantomData<*mut std::ops::Fn() + 'static>`
+   = help: within `[std::fmt::ArgumentV1<'_>]`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)`
+   = note: required because it appears within the type `std::marker::PhantomData<*mut (dyn std::ops::Fn() + 'static)>`
    = note: required because it appears within the type `core::fmt::Void`
    = note: required because it appears within the type `&core::fmt::Void`
    = note: required because it appears within the type `std::fmt::ArgumentV1<'_>`
@@ -18,14 +18,14 @@ note: required by `send`
 LL | fn send<T: Send>(_: T) {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0277]: `*mut std::ops::Fn() + 'static` cannot be shared between threads safely
+error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
   --> $DIR/send-sync.rs:19:5
    |
 LL |     sync(format_args!("{:?}", c)); //~ ERROR E0277
-   |     ^^^^ `*mut std::ops::Fn() + 'static` cannot be shared between threads safely
+   |     ^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
    |
-   = help: within `std::fmt::Arguments<'_>`, the trait `std::marker::Sync` is not implemented for `*mut std::ops::Fn() + 'static`
-   = note: required because it appears within the type `std::marker::PhantomData<*mut std::ops::Fn() + 'static>`
+   = help: within `std::fmt::Arguments<'_>`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)`
+   = note: required because it appears within the type `std::marker::PhantomData<*mut (dyn std::ops::Fn() + 'static)>`
    = note: required because it appears within the type `core::fmt::Void`
    = note: required because it appears within the type `&core::fmt::Void`
    = note: required because it appears within the type `std::fmt::ArgumentV1<'_>`
index a1c8ca77e41e8bf34ff228ae6c5470f98be8167a..efaee4095c1487a925c9437c992776004632c9a4 100644 (file)
 
 fn main() {
    let s = String::from("foo");
-   let mut gen = move || { //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
+   let mut gen = move || {
+   //~^ ERROR the size for value values of type
        yield s[..];
    };
-   unsafe { gen.resume(); } //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
+   unsafe { gen.resume(); }
+   //~^ ERROR the size for value values of type
 }
index 957fac172c2588dd071245ec89e53b1bd7b5e1cd..2938268a804ae1dfeb598a8dfbc6fa506920ed3e 100644 (file)
@@ -1,22 +1,25 @@
-error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
+error[E0277]: the size for value values of type `str` cannot be known at compilation time
   --> $DIR/sized-yield.rs:17:26
    |
-LL |      let mut gen = move || { //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
+LL |      let mut gen = move || {
    |  __________________________^
+LL | |    //~^ ERROR the size for value values of type
 LL | |        yield s[..];
 LL | |    };
-   | |____^ `str` does not have a constant size known at compile-time
+   | |____^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `str`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: the yield type of a generator must have a statically known size
 
-error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
-  --> $DIR/sized-yield.rs:20:17
+error[E0277]: the size for value values of type `str` cannot be known at compilation time
+  --> $DIR/sized-yield.rs:21:17
    |
-LL |    unsafe { gen.resume(); } //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
-   |                 ^^^^^^ `str` does not have a constant size known at compile-time
+LL |    unsafe { gen.resume(); }
+   |                 ^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `str`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
 
 error: aborting due to 2 previous errors
 
index abb3682a4987a3533b8b70b8d75c53e381f6b54b..f6b64b394fc12580dfceb696ee1799170aea1713 100644 (file)
@@ -25,7 +25,7 @@ fn cycle1() -> impl Clone {
     //~^ ERROR cycle detected
     //~| ERROR cycle detected
     send(cycle2().clone());
-    //~^ ERROR Send` is not satisfied
+    //~^ ERROR `std::rc::Rc<std::string::String>` cannot be sent between threads safely
 
     Rc::new(Cell::new(5))
 }
index 4537c96c4ab3b8319984f8f5d09d1c97604c38a5..b34facd2d39ce471e76832022c5f3ca92d66377f 100644 (file)
@@ -47,7 +47,7 @@ LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which again requires processing `cycle1::{{exist-impl-Trait}}`, completing the cycle
 
-error[E0277]: the trait bound `std::rc::Rc<std::string::String>: std::marker::Send` is not satisfied in `impl std::clone::Clone`
+error[E0277]: `std::rc::Rc<std::string::String>` cannot be sent between threads safely
   --> $DIR/auto-trait-leak.rs:27:5
    |
 LL |     send(cycle2().clone());
index 16310e67f1bb9c26f1f68d89302fb666886f0925..3c61543a711bd8f3762378c6a025d10ebd253e41 100644 (file)
@@ -23,10 +23,10 @@ fn send<T: Send>(_: T) {}
 
 fn main() {
     send(before());
-    //~^ ERROR the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied
+    //~^ ERROR `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
 
     send(after());
-    //~^ ERROR the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied
+    //~^ ERROR `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
 }
 
 // Deferred path, main has to wait until typeck finishes,
index 59623aed3d2b73fdb5b7c7854cc2f6c1d5653aaf..fb00c41f79c8f4c4e0fcbd357602c31bb8023ae7 100644 (file)
@@ -1,4 +1,4 @@
-error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied in `impl std::ops::Fn<(i32,)>`
+error[E0277]: `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
   --> $DIR/auto-trait-leak2.rs:25:5
    |
 LL |     send(before());
@@ -13,7 +13,7 @@ note: required by `send`
 LL | fn send<T: Send>(_: T) {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied in `impl std::ops::Fn<(i32,)>`
+error[E0277]: `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
   --> $DIR/auto-trait-leak2.rs:28:5
    |
 LL |     send(after());
index 57a0040600a255d506e893c997c8b983494b9479..b64caccd98abef8311b646deb96affdb375a3aeb 100644 (file)
@@ -34,8 +34,9 @@ fn projection_with_named_trait_is_disallowed(x: impl Iterator)
 fn projection_with_named_trait_inside_path_is_disallowed()
     -> <::std::ops::Range<impl Debug> as Iterator>::Item
 //~^ ERROR `impl Trait` is not allowed in path parameters
-{
-    (1i32..100).next().unwrap()
+//~| ERROR trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
+{ //~ ERROR trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
+    (1i32..100).next().unwrap() //~ ERROR mismatched types
 }
 
 fn projection_from_impl_trait_inside_dyn_trait_is_disallowed()
index f6d58984ecef747ae3994640d005c6380d7ae928..b495d4b4b010b82890183f7631cea963eedc3ab4 100644 (file)
@@ -17,7 +17,7 @@ LL |     -> <::std::ops::Range<impl Debug> as Iterator>::Item
    |                           ^^^^^^^^^^
 
 error[E0667]: `impl Trait` is not allowed in path parameters
-  --> $DIR/impl_trait_projections.rs:42:29
+  --> $DIR/impl_trait_projections.rs:43:29
    |
 LL |     -> <dyn Iterator<Item = impl Debug> as Iterator>::Item
    |                             ^^^^^^^^^^
@@ -30,7 +30,34 @@ LL | fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
    |
    = note: specify the type using the syntax `<impl std::iter::Iterator as Trait>::Item`
 
-error: aborting due to 5 previous errors
+error[E0277]: the trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
+  --> $DIR/impl_trait_projections.rs:38:1
+   |
+LL | / { //~ ERROR trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
+LL | |     (1i32..100).next().unwrap() //~ ERROR mismatched types
+LL | | }
+   | |_^ the trait `std::iter::Step` is not implemented for `impl std::fmt::Debug`
+   |
+   = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::ops::Range<impl std::fmt::Debug>`
+
+error[E0308]: mismatched types
+  --> $DIR/impl_trait_projections.rs:39:5
+   |
+LL |     (1i32..100).next().unwrap() //~ ERROR mismatched types
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected anonymized type, found i32
+   |
+   = note: expected type `impl std::fmt::Debug`
+              found type `i32`
+
+error[E0277]: the trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
+  --> $DIR/impl_trait_projections.rs:35:8
+   |
+LL |     -> <::std::ops::Range<impl Debug> as Iterator>::Item
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::iter::Step` is not implemented for `impl std::fmt::Debug`
+   |
+   = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::ops::Range<impl std::fmt::Debug>`
+
+error: aborting due to 8 previous errors
 
-Some errors occurred: E0223, E0667.
+Some errors occurred: E0223, E0277, E0308, E0667.
 For more information about an error, try `rustc --explain E0223`.
index 201470abe674cde98effb422f391cf95108a27a3..07b86228f61182466b75c15c17d784d6a8303cce 100644 (file)
@@ -10,8 +10,8 @@ note: first, the lifetime cannot outlive the lifetime 'a as defined on the funct
 LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...so that the expression is assignable:
-           expected std::boxed::Box<std::fmt::Debug>
-              found std::boxed::Box<std::fmt::Debug + 'a>
+           expected std::boxed::Box<dyn std::fmt::Debug>
+              found std::boxed::Box<(dyn std::fmt::Debug + 'a)>
    = note: but, the lifetime must be valid for the static lifetime...
    = note: ...so that the types are compatible:
            expected StaticTrait
index 37b586e1e3bd004dfb2e74007a750233aa0f85a1..169369c304eb22092fbfebaa2bc3ef638d08c3d3 100644 (file)
@@ -13,8 +13,8 @@ LL | |     }
    | |_____^
    = note: ...but the lifetime must also be valid for the static lifetime...
    = note: ...so that the method type is compatible with trait:
-           expected fn(&Struct) -> &Trait + 'static
-              found fn(&Struct) -> &Trait
+           expected fn(&Struct) -> &(dyn Trait + 'static)
+              found fn(&Struct) -> &dyn Trait
 
 error: aborting due to previous error
 
index a772d1f90cc0b5050ad4f4bab5c6bb2cad20695f..b0288463e9157432aa11bacb1c07e9d1d40b3e3c 100644 (file)
@@ -12,5 +12,6 @@
 use std::panic::catch_unwind;
 fn main() {
     let mut x = Cell::new(22);
-    catch_unwind(|| { x.set(23); }); //~ ERROR the trait bound
+    catch_unwind(|| { x.set(23); });
+    //~^ ERROR the type `std::cell::UnsafeCell<i32>` may contain interior mutability and a
 }
index 4c489c5964ba7b0b4fae3c8e03908f0f0cf7d2a9..f2aecc55ccb41ad3daf01e42fcbc3c998408b72d 100644 (file)
@@ -1,8 +1,8 @@
-error[E0277]: the trait bound `std::cell::UnsafeCell<i32>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::Cell<i32>`
+error[E0277]: the type `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
   --> $DIR/interior-mutability.rs:15:5
    |
-LL |     catch_unwind(|| { x.set(23); }); //~ ERROR the trait bound
-   |     ^^^^^^^^^^^^ the type std::cell::UnsafeCell<i32> may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
+LL |     catch_unwind(|| { x.set(23); });
+   |     ^^^^^^^^^^^^ `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
    |
    = help: within `std::cell::Cell<i32>`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<i32>`
    = note: required because it appears within the type `std::cell::Cell<i32>`
index c7b077014616c725793202a48b7b3cf415834337..5432d5f5ed910007cd5b76c1505801a7ad7bc86f 100644 (file)
@@ -13,10 +13,10 @@ fn main() {
     //~^ ERROR cast to unsized type: `&[usize; 2]` as `[usize]`
 
     let _bar = Box::new(1_usize) as std::fmt::Debug;
-    //~^ ERROR cast to unsized type: `std::boxed::Box<usize>` as `std::fmt::Debug`
+    //~^ ERROR cast to unsized type: `std::boxed::Box<usize>` as `dyn std::fmt::Debug`
 
     let _baz = 1_usize as std::fmt::Debug;
-    //~^ ERROR cast to unsized type: `usize` as `std::fmt::Debug`
+    //~^ ERROR cast to unsized type: `usize` as `dyn std::fmt::Debug`
 
     let _quux = [1_usize, 2] as [usize];
     //~^ ERROR cast to unsized type: `[usize; 2]` as `[usize]`
index 80ba49cce1a0cc5091469a2c11589463db269268..6c7e883f9f9c2c118c5354a6ec93cd9673a9e2c6 100644 (file)
@@ -10,7 +10,7 @@ help: consider using an implicit coercion to `&[usize]` instead
 LL |     let _foo = &[1_usize, 2] as [usize];
    |                ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0620]: cast to unsized type: `std::boxed::Box<usize>` as `std::fmt::Debug`
+error[E0620]: cast to unsized type: `std::boxed::Box<usize>` as `dyn std::fmt::Debug`
   --> $DIR/issue-17441.rs:15:16
    |
 LL |     let _bar = Box::new(1_usize) as std::fmt::Debug;
@@ -18,7 +18,7 @@ LL |     let _bar = Box::new(1_usize) as std::fmt::Debug;
    |                                     |
    |                                     help: try casting to a `Box` instead: `Box<std::fmt::Debug>`
 
-error[E0620]: cast to unsized type: `usize` as `std::fmt::Debug`
+error[E0620]: cast to unsized type: `usize` as `dyn std::fmt::Debug`
   --> $DIR/issue-17441.rs:18:16
    |
 LL |     let _baz = 1_usize as std::fmt::Debug;
diff --git a/src/test/ui/issue-19100.fixed b/src/test/ui/issue-19100.fixed
new file mode 100644 (file)
index 0000000..3ced913
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// run-pass
+// run-rustfix
+
+#![allow(non_snake_case)]
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+#[derive(Copy, Clone)]
+enum Foo {
+    Bar,
+    Baz
+}
+
+impl Foo {
+    fn foo(&self) {
+        match self {
+            &
+Foo::Bar if true
+//~^ WARN pattern binding `Bar` is named the same as one of the variants of the type `Foo`
+=> println!("bar"),
+            &
+Foo::Baz if false
+//~^ WARN pattern binding `Baz` is named the same as one of the variants of the type `Foo`
+=> println!("baz"),
+_ => ()
+        }
+    }
+}
+
+fn main() {}
index 2032f23e6a30e0feb33e0c151c0e2ba5853e32b5..e073bf9076160eb23e9d9641c68e93ae9017a4a1 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 // run-pass
+// run-rustfix
 
 #![allow(non_snake_case)]
 #![allow(dead_code)]
index 96835f69b78c772be9bf57b17cb294b3c464591d..34dc29c63df72029d7b34183ec9748ee939bbb50 100644 (file)
@@ -1,16 +1,12 @@
 warning[E0170]: pattern binding `Bar` is named the same as one of the variants of the type `Foo`
-  --> $DIR/issue-19100.rs:27:1
+  --> $DIR/issue-19100.rs:28:1
    |
 LL | Bar if true
-   | ^^^
-   |
-   = help: if you meant to match on a variant, consider making the path in the pattern qualified: `Foo::Bar`
+   | ^^^ help: to match on the variant, qualify the path: `Foo::Bar`
 
 warning[E0170]: pattern binding `Baz` is named the same as one of the variants of the type `Foo`
-  --> $DIR/issue-19100.rs:31:1
+  --> $DIR/issue-19100.rs:32:1
    |
 LL | Baz if false
-   | ^^^
-   |
-   = help: if you meant to match on a variant, consider making the path in the pattern qualified: `Foo::Baz`
+   | ^^^ help: to match on the variant, qualify the path: `Foo::Baz`
 
index 1316773f6b789d3e088279779c94f1b9ac92c7f7..156ebd920f0d95e0955076b931625c61bd7a105e 100644 (file)
@@ -13,7 +13,7 @@ LL |     let _ = x
    |             ^ the trait `Array` cannot be made into an object
    |
    = note: the trait cannot require that `Self : Sized`
-   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&Array>` for `&T`
+   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Array>` for `&T`
 
 error: aborting due to 2 previous errors
 
index 42dfdadf9c46f1d505a3a436cdf3ad26d82ba787..fa3cb92b180e06e2be7903c3864e6c995309b1a5 100644 (file)
@@ -2,9 +2,7 @@ warning[E0170]: pattern binding `Nil` is named the same as one of the variants o
   --> $DIR/issue-30302.rs:23:9
    |
 LL |         Nil => true,
-   |         ^^^
-   |
-   = help: if you meant to match on a variant, consider making the path in the pattern qualified: `Stack::Nil`
+   |         ^^^ help: to match on the variant, qualify the path: `Stack::Nil`
 
 error: unreachable pattern
   --> $DIR/issue-30302.rs:25:9
diff --git a/src/test/ui/issue-50577.rs b/src/test/ui/issue-50577.rs
new file mode 100644 (file)
index 0000000..a3bb687
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    enum Foo {
+        Drop = assert_eq!(1, 1)
+    }
+}
diff --git a/src/test/ui/issue-50577.stderr b/src/test/ui/issue-50577.stderr
new file mode 100644 (file)
index 0000000..8751303
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0317]: if may be missing an else clause
+  --> $DIR/issue-50577.rs:13:16
+   |
+LL |         Drop = assert_eq!(1, 1)
+   |                ^^^^^^^^^^^^^^^^ expected (), found isize
+   |
+   = note: expected type `()`
+              found type `isize`
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0317`.
diff --git a/src/test/ui/issue-50585.rs b/src/test/ui/issue-50585.rs
new file mode 100644 (file)
index 0000000..0c063d4
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    |y: Vec<[(); for x in 0..2 {}]>| {};
+    //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/issue-50585.stderr b/src/test/ui/issue-50585.stderr
new file mode 100644 (file)
index 0000000..3f9328d
--- /dev/null
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-50585.rs:12:18
+   |
+LL | fn main() {
+   |           - expected `()` because of default return type
+LL |     |y: Vec<[(); for x in 0..2 {}]>| {};
+   |                  ^^^^^^^^^^^^^^^^ expected usize, found ()
+   |
+   = note: expected type `usize`
+              found type `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issue-50781.rs b/src/test/ui/issue-50781.rs
new file mode 100644 (file)
index 0000000..4383086
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![deny(where_clauses_object_safety)]
+
+trait Trait {}
+
+trait X {
+    fn foo(&self) where Self: Trait; //~ ERROR the trait `X` cannot be made into an object
+    //~^ WARN this was previously accepted by the compiler but is being phased out
+}
+
+impl X for () {
+    fn foo(&self) {}
+}
+
+impl Trait for dyn X {}
+
+pub fn main() {
+    // Check that this does not segfault.
+    <X as X>::foo(&());
+}
diff --git a/src/test/ui/issue-50781.stderr b/src/test/ui/issue-50781.stderr
new file mode 100644 (file)
index 0000000..047b847
--- /dev/null
@@ -0,0 +1,17 @@
+error: the trait `X` cannot be made into an object
+  --> $DIR/issue-50781.rs:16:5
+   |
+LL |     fn foo(&self) where Self: Trait; //~ ERROR the trait `X` cannot be made into an object
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/issue-50781.rs:11:9
+   |
+LL | #![deny(where_clauses_object_safety)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = 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 #51443 <https://github.com/rust-lang/rust/issues/51443>
+   = note: method `foo` references the `Self` type in where clauses
+
+error: aborting due to previous error
+
index f9486fa57b136eccf30f45a685a3cbf897f030fd..831c3e5fda084c560f01c0676303e1ea99a85ad4 100644 (file)
@@ -9,4 +9,4 @@
 // except according to those terms.
 
 fn main<'a>() { }
-    //~^ ERROR `main` function is not allowed to have lifetime parameters [E0131]
+    //~^ ERROR `main` function is not allowed to have generic parameters [E0131]
index 3b691bbb0330f587f82f381477a1e64e6233a6f9..1daa8dfbba689ec3b55edc3daf15dbf6da8f8932 100644 (file)
@@ -1,8 +1,8 @@
-error[E0131]: `main` function is not allowed to have lifetime parameters
+error[E0131]: `main` function is not allowed to have generic parameters
   --> $DIR/issue-51022.rs:11:8
    |
 LL | fn main<'a>() { }
-   |        ^^^^ `main` cannot have lifetime parameters
+   |        ^^^^ `main` cannot have generic parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-51714.rs b/src/test/ui/issue-51714.rs
new file mode 100644 (file)
index 0000000..96c5b92
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    |_:  [_; return || {}] | {}
+    //~^ ERROR return statement outside of function body
+}
+
+fn foo() {
+    [(); return || {}];
+    //~^ ERROR return statement outside of function body
+}
diff --git a/src/test/ui/issue-51714.stderr b/src/test/ui/issue-51714.stderr
new file mode 100644 (file)
index 0000000..746adea
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0572]: return statement outside of function body
+  --> $DIR/issue-51714.rs:12:14
+   |
+LL |     |_:  [_; return || {}] | {}
+   |              ^^^^^^^^^^^^
+
+error[E0572]: return statement outside of function body
+  --> $DIR/issue-51714.rs:17:10
+   |
+LL |     [(); return || {}];
+   |          ^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0572`.
index 4b20001457f78216b5a1feeb7f29d17feddb718b..7f22dc8739e76a6a42b47382d5eb282e95103ff5 100644 (file)
@@ -59,7 +59,7 @@ pub struct StructWithProjectionAndLifetime<'a>(
     pub fn char_type(p: char); //~ ERROR uses type `char`
     pub fn i128_type(p: i128); //~ ERROR uses type `i128`
     pub fn u128_type(p: u128); //~ ERROR uses type `u128`
-    pub fn trait_type(p: &Clone); //~ ERROR uses type `std::clone::Clone`
+    pub fn trait_type(p: &Clone); //~ ERROR uses type `dyn std::clone::Clone`
     pub fn tuple_type(p: (i32, i32)); //~ ERROR uses type `(i32, i32)`
     pub fn tuple_type2(p: I32Pair); //~ ERROR uses type `(i32, i32)`
     pub fn zero_size(p: ZeroSize); //~ ERROR struct has no fields
index 76b500e7d23bfe5058ff5a8590694296a54657f2..d1ef3a7a19c294b7983399a3c4813b724197b192 100644 (file)
@@ -73,10 +73,10 @@ error: `extern` block uses type `u128` which is not FFI-safe: 128-bit integers d
 LL |     pub fn u128_type(p: u128); //~ ERROR uses type `u128`
    |                         ^^^^
 
-error: `extern` block uses type `std::clone::Clone` which is not FFI-safe: trait objects have no C equivalent
+error: `extern` block uses type `dyn std::clone::Clone` which is not FFI-safe: trait objects have no C equivalent
   --> $DIR/lint-ctypes.rs:62:26
    |
-LL |     pub fn trait_type(p: &Clone); //~ ERROR uses type `std::clone::Clone`
+LL |     pub fn trait_type(p: &Clone); //~ ERROR uses type `dyn std::clone::Clone`
    |                          ^^^^^^
 
 error: `extern` block uses type `(i32, i32)` which is not FFI-safe: tuples have unspecified layout
diff --git a/src/test/ui/lint/trivial-casts-featuring-type-ascription.rs b/src/test/ui/lint/trivial-casts-featuring-type-ascription.rs
new file mode 100644 (file)
index 0000000..fba3724
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![deny(trivial_casts, trivial_numeric_casts)]
+#![feature(type_ascription)]
+
+fn main() {
+    let lugubrious = 12i32 as i32;
+    //~^ ERROR trivial numeric cast
+    let haunted: &u32 = &99;
+    let _ = haunted as *const u32;
+    //~^ ERROR trivial cast
+}
diff --git a/src/test/ui/lint/trivial-casts-featuring-type-ascription.stderr b/src/test/ui/lint/trivial-casts-featuring-type-ascription.stderr
new file mode 100644 (file)
index 0000000..a77135c
--- /dev/null
@@ -0,0 +1,28 @@
+error: trivial numeric cast: `i32` as `i32`
+  --> $DIR/trivial-casts-featuring-type-ascription.rs:15:22
+   |
+LL |     let lugubrious = 12i32 as i32;
+   |                      ^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/trivial-casts-featuring-type-ascription.rs:11:24
+   |
+LL | #![deny(trivial_casts, trivial_numeric_casts)]
+   |                        ^^^^^^^^^^^^^^^^^^^^^
+   = help: cast can be replaced by coercion; this might require type ascription or a temporary variable
+
+error: trivial cast: `&u32` as `*const u32`
+  --> $DIR/trivial-casts-featuring-type-ascription.rs:18:13
+   |
+LL |     let _ = haunted as *const u32;
+   |             ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/trivial-casts-featuring-type-ascription.rs:11:9
+   |
+LL | #![deny(trivial_casts, trivial_numeric_casts)]
+   |         ^^^^^^^^^^^^^
+   = help: cast can be replaced by coercion; this might require type ascription or a temporary variable
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/lint/trivial-casts.rs b/src/test/ui/lint/trivial-casts.rs
new file mode 100644 (file)
index 0000000..759b282
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![deny(trivial_casts, trivial_numeric_casts)]
+
+fn main() {
+    let lugubrious = 12i32 as i32;
+    //~^ ERROR trivial numeric cast
+    let haunted: &u32 = &99;
+    let _ = haunted as *const u32;
+    //~^ ERROR trivial cast
+}
diff --git a/src/test/ui/lint/trivial-casts.stderr b/src/test/ui/lint/trivial-casts.stderr
new file mode 100644 (file)
index 0000000..d52869f
--- /dev/null
@@ -0,0 +1,28 @@
+error: trivial numeric cast: `i32` as `i32`
+  --> $DIR/trivial-casts.rs:14:22
+   |
+LL |     let lugubrious = 12i32 as i32;
+   |                      ^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/trivial-casts.rs:11:24
+   |
+LL | #![deny(trivial_casts, trivial_numeric_casts)]
+   |                        ^^^^^^^^^^^^^^^^^^^^^
+   = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: trivial cast: `&u32` as `*const u32`
+  --> $DIR/trivial-casts.rs:17:13
+   |
+LL |     let _ = haunted as *const u32;
+   |             ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/trivial-casts.rs:11:9
+   |
+LL | #![deny(trivial_casts, trivial_numeric_casts)]
+   |         ^^^^^^^^^^^^^
+   = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: aborting due to 2 previous errors
+
index 6a69e7cc717208a2c0a19970802ff4d1ef9e0005..79442bd108a6759fe1ef27761d6e5309935bbf50 100644 (file)
@@ -9,8 +9,8 @@ LL | |         _ => y,
 LL | |     };
    | |_____^ expected bound lifetime parameter 'a, found concrete lifetime
    |
-   = note: expected type `&for<'a, 'b> Foo<&'a u8, &'b u8>`
-              found type `&for<'a> Foo<&'a u8, &'a u8>`
+   = note: expected type `&dyn for<'a, 'b> Foo<&'a u8, &'b u8>`
+              found type `&dyn for<'a> Foo<&'a u8, &'a u8>`
    = note: this was previously accepted by the compiler but has been phased out
    = note: for more information, see https://github.com/rust-lang/rust/issues/45852
 
index 3f2cb59b11dee4f189eb36f543fe151c9fec17b2..86785f24f3637fbc9a9a059ece035cdd9c5dff5d 100644 (file)
@@ -13,6 +13,6 @@ fn main() {
     2 as usize - Some(1); //~ ERROR cannot subtract `std::option::Option<{integer}>` from `usize`
     3 * (); //~ ERROR cannot multiply `()` to `{integer}`
     4 / ""; //~ ERROR cannot divide `{integer}` by `&str`
-    5 < String::new(); //~ ERROR is not satisfied
-    6 == Ok(1); //~ ERROR is not satisfied
+    5 < String::new(); //~ ERROR can't compare `{integer}` with `std::string::String`
+    6 == Ok(1); //~ ERROR can't compare `{integer}` with `std::result::Result<{integer}, _>`
 }
index 9d23b256fd333bee352c51ff796d2c21630ae910..4c6d95efadb1557fa071bb0c560f8e00f6bcb4cd 100644 (file)
@@ -30,19 +30,19 @@ LL |     4 / ""; //~ ERROR cannot divide `{integer}` by `&str`
    |
    = help: the trait `std::ops::Div<&str>` is not implemented for `{integer}`
 
-error[E0277]: the trait bound `{integer}: std::cmp::PartialOrd<std::string::String>` is not satisfied
+error[E0277]: can't compare `{integer}` with `std::string::String`
   --> $DIR/binops.rs:16:7
    |
-LL |     5 < String::new(); //~ ERROR is not satisfied
-   |       ^ can't compare `{integer}` with `std::string::String`
+LL |     5 < String::new(); //~ ERROR can't compare `{integer}` with `std::string::String`
+   |       ^ no implementation for `{integer} < std::string::String` and `{integer} > std::string::String`
    |
    = help: the trait `std::cmp::PartialOrd<std::string::String>` is not implemented for `{integer}`
 
-error[E0277]: the trait bound `{integer}: std::cmp::PartialEq<std::result::Result<{integer}, _>>` is not satisfied
+error[E0277]: can't compare `{integer}` with `std::result::Result<{integer}, _>`
   --> $DIR/binops.rs:17:7
    |
-LL |     6 == Ok(1); //~ ERROR is not satisfied
-   |       ^^ can't compare `{integer}` with `std::result::Result<{integer}, _>`
+LL |     6 == Ok(1); //~ ERROR can't compare `{integer}` with `std::result::Result<{integer}, _>`
+   |       ^^ no implementation for `{integer} == std::result::Result<{integer}, _>`
    |
    = help: the trait `std::cmp::PartialEq<std::result::Result<{integer}, _>>` is not implemented for `{integer}`
 
index 15388b3a7647f9625e894f76069a61ce6ca8deb0..d76c4a015a2c2f5236ee0b5598f54d28d4110dba 100644 (file)
@@ -60,7 +60,7 @@ fn main()
 
     let _ = 42usize as *const [u8]; //~ ERROR is invalid
     let _ = v as *const [u8]; //~ ERROR cannot cast
-    let _ = fat_v as *const Foo; //~ ERROR is not satisfied
+    let _ = fat_v as *const Foo; //~ ERROR the size for value values of type
     let _ = foo as *const str; //~ ERROR is invalid
     let _ = foo as *mut str; //~ ERROR is invalid
     let _ = main as *mut str; //~ ERROR is invalid
@@ -69,7 +69,7 @@ fn main()
     let _ = fat_sv as usize; //~ ERROR is invalid
 
     let a : *const str = "hello";
-    let _ = a as *const Foo; //~ ERROR is not satisfied
+    let _ = a as *const Foo; //~ ERROR the size for value values of type
 
     // check no error cascade
     let _ = main.f as *const u32; //~ ERROR no field
index 7931e7ff07f4ce55d4e5d573d3f49daa077f8278..9335795f6b8f322c0d3d0e6355f6ff61d0a025c1 100644 (file)
@@ -162,13 +162,13 @@ error[E0607]: cannot cast thin pointer `*const u8` to fat pointer `*const [u8]`
 LL |     let _ = v as *const [u8]; //~ ERROR cannot cast
    |             ^^^^^^^^^^^^^^^^
 
-error[E0606]: casting `&Foo` as `*const str` is invalid
+error[E0606]: casting `&dyn Foo` as `*const str` is invalid
   --> $DIR/cast-rfc0401.rs:64:13
    |
 LL |     let _ = foo as *const str; //~ ERROR is invalid
    |             ^^^^^^^^^^^^^^^^^
 
-error[E0606]: casting `&Foo` as `*mut str` is invalid
+error[E0606]: casting `&dyn Foo` as `*mut str` is invalid
   --> $DIR/cast-rfc0401.rs:65:13
    |
 LL |     let _ = foo as *mut str; //~ ERROR is invalid
@@ -200,7 +200,7 @@ LL |     let _ = fat_sv as usize; //~ ERROR is invalid
    |
    = help: cast through a thin pointer first
 
-error[E0606]: casting `*const Foo` as `*const [u16]` is invalid
+error[E0606]: casting `*const dyn Foo` as `*const [u16]` is invalid
   --> $DIR/cast-rfc0401.rs:78:13
    |
 LL |     let _ = cf as *const [u16]; //~ ERROR is invalid
@@ -208,7 +208,7 @@ LL |     let _ = cf as *const [u16]; //~ ERROR is invalid
    |
    = note: vtable kinds may not match
 
-error[E0606]: casting `*const Foo` as `*const Bar` is invalid
+error[E0606]: casting `*const dyn Foo` as `*const dyn Bar` is invalid
   --> $DIR/cast-rfc0401.rs:79:13
    |
 LL |     let _ = cf as *const Bar; //~ ERROR is invalid
@@ -216,23 +216,25 @@ LL |     let _ = cf as *const Bar; //~ ERROR is invalid
    |
    = note: vtable kinds may not match
 
-error[E0277]: the trait bound `[u8]: std::marker::Sized` is not satisfied
+error[E0277]: the size for value values of type `[u8]` cannot be known at compilation time
   --> $DIR/cast-rfc0401.rs:63:13
    |
-LL |     let _ = fat_v as *const Foo; //~ ERROR is not satisfied
-   |             ^^^^^ `[u8]` does not have a constant size known at compile-time
+LL |     let _ = fat_v as *const Foo; //~ ERROR the size for value values of type
+   |             ^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `[u8]`
-   = note: required for the cast to the object type `Foo`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
+   = note: required for the cast to the object type `dyn Foo`
 
-error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
+error[E0277]: the size for value values of type `str` cannot be known at compilation time
   --> $DIR/cast-rfc0401.rs:72:13
    |
-LL |     let _ = a as *const Foo; //~ ERROR is not satisfied
-   |             ^ `str` does not have a constant size known at compile-time
+LL |     let _ = a as *const Foo; //~ ERROR the size for value values of type
+   |             ^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `str`
-   = note: required for the cast to the object type `Foo`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
+   = note: required for the cast to the object type `dyn Foo`
 
 error[E0606]: casting `&{float}` as `f32` is invalid
   --> $DIR/cast-rfc0401.rs:81:30
index c838c617ae4534beba91cc99724e2b0b55d671e8..018ea941d12da20a3aadde361ed388a64718f0ad 100644 (file)
@@ -2,12 +2,12 @@ error[E0308]: mismatched types
   --> $DIR/issue-19109.rs:14:5
    |
 LL | fn function(t: &mut Trait) {
-   |                            - help: try adding a return type: `-> *mut Trait`
+   |                            - help: try adding a return type: `-> *mut dyn Trait`
 LL |     t as *mut Trait
    |     ^^^^^^^^^^^^^^^ expected (), found *-ptr
    |
    = note: expected type `()`
-              found type `*mut Trait`
+              found type `*mut dyn Trait`
 
 error: aborting due to previous error
 
index bbe9053430a1c8ff994b3fba02898a9d7f1cc1f9..15c9fd6bf8fe83d0ba22ea764f7eb148e854623c 100644 (file)
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     a(x); //~ ERROR mismatched types [E0308]
    |       ^ expected trait `Foo + std::marker::Send`, found trait `Foo`
    |
-   = note: expected type `std::boxed::Box<Foo + std::marker::Send + 'static>`
-              found type `std::boxed::Box<Foo + 'static>`
+   = note: expected type `std::boxed::Box<(dyn Foo + std::marker::Send + 'static)>`
+              found type `std::boxed::Box<(dyn Foo + 'static)>`
 
 error: aborting due to previous error
 
index 6ebbf670acd9f7e681fdc9962c3cde773c52e792..d5b18a6c9629848f3227acb2fc4a96c607e22f53 100644 (file)
@@ -7,7 +7,7 @@ LL |         Foo {f} => {}
 LL |     touch(&x); //~ ERROR use of partially moved value: `x`
    |           ^^ value borrowed here after move
    |
-   = note: move occurs because `x` has type `Foo<std::string::String>`, which does not implement the `Copy` trait
+   = note: move occurs because `x.f` has type `std::string::String`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/issue-51512.rs b/src/test/ui/nll/issue-51512.rs
new file mode 100644 (file)
index 0000000..4543d2b
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(warnings)]
+#![feature(nll)]
+
+fn main() {
+    let range = 0..1;
+    let r = range;
+    let x = range.start;
+    //~^ ERROR use of moved value: `range.start` [E0382]
+}
diff --git a/src/test/ui/nll/issue-51512.stderr b/src/test/ui/nll/issue-51512.stderr
new file mode 100644 (file)
index 0000000..102de43
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0382]: use of moved value: `range.start`
+  --> $DIR/issue-51512.rs:17:13
+   |
+LL |     let r = range;
+   |             ----- value moved here
+LL |     let x = range.start;
+   |             ^^^^^^^^^^^ value used here after move
+   |
+   = note: move occurs because `range` has type `std::ops::Range<i32>`, which does not implement the `Copy` trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.
index 3689ca74adb8c304dc0b29796a0def435feba9ed..e07051135779ac6344bf4ba4fee317964e54fa76 100644 (file)
@@ -20,7 +20,7 @@ LL |     with_signature(x, |mut y| Box::new(y.next()))
                '_#1r,
                T,
                i32,
-               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#2r>
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#2r)>
            ]
    = note: number of external vids: 3
    = note: where <T as std::iter::Iterator>::Item: '_#2r
@@ -60,7 +60,7 @@ LL |     with_signature(x, |mut y| Box::new(y.next()))
                '_#1r,
                T,
                i32,
-               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#2r>
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#2r)>
            ]
    = note: number of external vids: 3
    = note: where <T as std::iter::Iterator>::Item: '_#2r
@@ -92,7 +92,7 @@ LL |     with_signature(x, |mut y| Box::new(y.next()))
                '_#2r,
                T,
                i32,
-               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#3r>
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#3r)>
            ]
    = note: number of external vids: 4
    = note: where <T as std::iter::Iterator>::Item: '_#3r
@@ -134,7 +134,7 @@ LL |     with_signature(x, |mut y| Box::new(y.next()))
                '_#2r,
                T,
                i32,
-               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#3r>
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#3r)>
            ]
    = note: number of external vids: 4
    = note: where <T as std::iter::Iterator>::Item: '_#3r
index 59a8a39a7b0857359cbf8d220c3b6ee4ed7053cf..39ad96cc6cd8e9ac47a75859080aadccc4a2df21 100644 (file)
@@ -20,7 +20,7 @@ LL |     with_signature(x, |y| y)
                '_#1r,
                T,
                i32,
-               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<std::fmt::Debug + '_#2r>
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn std::fmt::Debug + '_#2r)>
            ]
    = note: number of external vids: 3
    = note: where T: '_#2r
diff --git a/src/test/ui/no-args-non-move-async-closure.rs b/src/test/ui/no-args-non-move-async-closure.rs
new file mode 100644 (file)
index 0000000..f2ecc44
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: --edition=2018
+
+#![feature(arbitrary_self_types, async_await, await_macro, futures_api, pin)]
+
+fn main() {
+    let _ = async |x: u8| {};
+    //~^ ERROR `async` non-`move` closures with arguments are not currently supported
+}
diff --git a/src/test/ui/no-args-non-move-async-closure.stderr b/src/test/ui/no-args-non-move-async-closure.stderr
new file mode 100644 (file)
index 0000000..7528165
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0708]: `async` non-`move` closures with arguments are not currently supported
+  --> $DIR/no-args-non-move-async-closure.rs:16:13
+   |
+LL |     let _ = async |x: u8| {};
+   |             ^^^^^^^^^^^^^
+   |
+   = help: consider using `let` statements to manually capture variables by reference before entering an `async move` closure
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0708`.
diff --git a/src/test/ui/parser/expected-comma-found-token.rs b/src/test/ui/parser/expected-comma-found-token.rs
new file mode 100644 (file)
index 0000000..3c53c3a
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Tests that two closures cannot simultaneously have mutable
+// access to the variable, whether that mutable access be used
+// for direct assignment or for taking mutable ref. Issue #6801.
+
+#![feature(on_unimplemented)]
+
+#[rustc_on_unimplemented(
+    message="the message"
+    label="the label"
+)]
+trait T {}
+//~^^^ ERROR expected one of `)` or `,`, found `label`
diff --git a/src/test/ui/parser/expected-comma-found-token.stderr b/src/test/ui/parser/expected-comma-found-token.stderr
new file mode 100644 (file)
index 0000000..9a564bb
--- /dev/null
@@ -0,0 +1,10 @@
+error: expected one of `)` or `,`, found `label`
+  --> $DIR/expected-comma-found-token.rs:19:5
+   |
+LL |     message="the message"
+   |                          - expected one of `)` or `,` here
+LL |     label="the label"
+   |     ^^^^^ unexpected token
+
+error: aborting due to previous error
+
index c813b64d40b58ddde391f8f185b286898dba871d..43f13d45684e8c7ee46cdf5d1ce08fc74422e91d 100644 (file)
@@ -1,8 +1,8 @@
-error[E0277]: the trait bound `&T: std::cmp::PartialEq<T>` is not satisfied
+error[E0277]: can't compare `&T` with `T`
   --> $DIR/partialeq_help.rs:12:7
    |
 LL |     a == b; //~ ERROR E0277
-   |       ^^ can't compare `&T` with `T`
+   |       ^^ no implementation for `&T == T`
    |
    = help: the trait `std::cmp::PartialEq<T>` is not implemented for `&T`
    = help: consider adding a `where &T: std::cmp::PartialEq<T>` bound
index 7005088965df13f78e0b53e8922e873fdfeea3b6..de755dd6a4602e2a6ec4a0da0f86091bdd1c6614 100644 (file)
@@ -1,4 +1,4 @@
-error: incorrect visibility restriction
+error[E0704]: incorrect visibility restriction
   --> $DIR/pub-restricted.rs:15:6
    |
 LL | pub (a) fn afn() {} //~ incorrect visibility restriction
@@ -9,7 +9,7 @@ LL | pub (a) fn afn() {} //~ incorrect visibility restriction
            `pub(super)`: visible only in the current module's parent
            `pub(in path::to::module)`: visible only on the specified path
 
-error: incorrect visibility restriction
+error[E0704]: incorrect visibility restriction
   --> $DIR/pub-restricted.rs:16:6
    |
 LL | pub (b) fn bfn() {} //~ incorrect visibility restriction
@@ -20,7 +20,7 @@ LL | pub (b) fn bfn() {} //~ incorrect visibility restriction
            `pub(super)`: visible only in the current module's parent
            `pub(in path::to::module)`: visible only on the specified path
 
-error: incorrect visibility restriction
+error[E0704]: incorrect visibility restriction
   --> $DIR/pub-restricted.rs:32:14
    |
 LL |         pub (a) invalid: usize, //~ incorrect visibility restriction
@@ -31,7 +31,7 @@ LL |         pub (a) invalid: usize, //~ incorrect visibility restriction
            `pub(super)`: visible only in the current module's parent
            `pub(in path::to::module)`: visible only on the specified path
 
-error: incorrect visibility restriction
+error[E0704]: incorrect visibility restriction
   --> $DIR/pub-restricted.rs:41:6
    |
 LL | pub (xyz) fn xyz() {} //~ incorrect visibility restriction
@@ -50,3 +50,4 @@ LL |         pub (in x) non_parent_invalid: usize, //~ ERROR visibilities can on
 
 error: aborting due to 5 previous errors
 
+For more information about this error, try `rustc --explain E0704`.
index 83ff95cc2ea48f59c0086e69e970eb4a3aa1752f..ca854f9f70122c2b4750bac48c658447f6fa7a13 100644 (file)
@@ -11,6 +11,7 @@
 trait I {}
 type K = I+'static;
 
-fn foo(_x: K) {} //~ ERROR: `I + 'static: std::marker::Sized` is not satisfied
+fn foo(_x: K) {}
+//~^ ERROR the size for value values of type
 
 fn main() {}
index 92309274e844279f3b18846115cf1816f20a5c23..72bd270165fd09240f7bf584f4fff4466e0e96f5 100644 (file)
@@ -1,10 +1,11 @@
-error[E0277]: the trait bound `I + 'static: std::marker::Sized` is not satisfied
+error[E0277]: the size for value values of type `(dyn I + 'static)` cannot be known at compilation time
   --> $DIR/issue-5035-2.rs:14:8
    |
-LL | fn foo(_x: K) {} //~ ERROR: `I + 'static: std::marker::Sized` is not satisfied
-   |        ^^ `I + 'static` does not have a constant size known at compile-time
+LL | fn foo(_x: K) {}
+   |        ^^ doesn't have a size known at compile-time
    |
-   = help: the trait `std::marker::Sized` is not implemented for `I + 'static`
+   = help: the trait `std::marker::Sized` is not implemented for `(dyn I + 'static)`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: all local variables must have a statically known size
 
 error: aborting due to previous error
index ed96570583f4ffb4bbda6230eaa2a5438f686b9d..8c31ab2ca88e4d71a88dda2c6d1b759b1c3444d0 100644 (file)
@@ -20,13 +20,13 @@ error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/collections.rs:33:50
    |
 LL |     fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>;
-   |                                                  ^^^^^ lifetime parameter not allowed on this type
+   |                                                  ^^^^^ lifetime parameter not allowed
 
 error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/collections.rs:59:50
    |
 LL |     fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> {
-   |                                                  ^^^^^ lifetime parameter not allowed on this type
+   |                                                  ^^^^^ lifetime parameter not allowed
 
 error: aborting due to 5 previous errors
 
index 764a0db2478a8478d7d86dd03758905bf9db48f4..1746122eb49f41d68b726acf25b086e6cda7e555 100644 (file)
@@ -2,19 +2,19 @@ error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/construct_with_other_type.rs:26:46
    |
 LL |     type Baa<'a>: Deref<Target = <Self::Quux<'a> as Foo>::Bar<'a, 'static>>;
-   |                                              ^^ lifetime parameter not allowed on this type
+   |                                              ^^ lifetime parameter not allowed
 
 error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/construct_with_other_type.rs:26:63
    |
 LL |     type Baa<'a>: Deref<Target = <Self::Quux<'a> as Foo>::Bar<'a, 'static>>;
-   |                                                               ^^ lifetime parameter not allowed on this type
+   |                                                               ^^ lifetime parameter not allowed
 
 error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/construct_with_other_type.rs:34:40
    |
 LL |     type Baa<'a> = &'a <T as Foo>::Bar<'a, 'static>;
-   |                                        ^^ lifetime parameter not allowed on this type
+   |                                        ^^ lifetime parameter not allowed
 
 error: aborting due to 3 previous errors
 
index 64e82c0d1097ffc1de33bf470488046bb9d4f9a5..d48c21477b310668bfa620ace9f6314c561a08e0 100644 (file)
@@ -14,19 +14,19 @@ error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/generic_associated_type_undeclared_lifetimes.rs:20:47
    |
 LL |     type Iter<'a>: Iterator<Item = Self::Item<'a>>
-   |                                               ^^ lifetime parameter not allowed on this type
+   |                                               ^^ lifetime parameter not allowed
 
 error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/generic_associated_type_undeclared_lifetimes.rs:22:37
    |
 LL |         + Deref<Target = Self::Item<'b>>;
-   |                                     ^^ lifetime parameter not allowed on this type
+   |                                     ^^ lifetime parameter not allowed
 
 error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/generic_associated_type_undeclared_lifetimes.rs:26:41
    |
 LL |     fn iter<'a>(&'a self) -> Self::Iter<'undeclared>;
-   |                                         ^^^^^^^^^^^ lifetime parameter not allowed on this type
+   |                                         ^^^^^^^^^^^ lifetime parameter not allowed
 
 error: aborting due to 5 previous errors
 
index 0e251300e451f8bb49eae67a15577a72ead73977..737a29ec2c8be46ced3f82ad9674b416b6ca9b73 100644 (file)
@@ -2,37 +2,37 @@ error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/iterable.rs:20:47
    |
 LL |     type Iter<'a>: Iterator<Item = Self::Item<'a>>;
-   |                                               ^^ lifetime parameter not allowed on this type
+   |                                               ^^ lifetime parameter not allowed
 
 error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/iterable.rs:49:53
    |
 LL | fn make_iter<'a, I: Iterable>(it: &'a I) -> I::Iter<'a> {
-   |                                                     ^^ lifetime parameter not allowed on this type
+   |                                                     ^^ lifetime parameter not allowed
 
 error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/iterable.rs:54:60
    |
 LL | fn get_first<'a, I: Iterable>(it: &'a I) -> Option<I::Item<'a>> {
-   |                                                            ^^ lifetime parameter not allowed on this type
+   |                                                            ^^ lifetime parameter not allowed
 
 error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/iterable.rs:23:41
    |
 LL |     fn iter<'a>(&'a self) -> Self::Iter<'a>;
-   |                                         ^^ lifetime parameter not allowed on this type
+   |                                         ^^ lifetime parameter not allowed
 
 error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/iterable.rs:32:41
    |
 LL |     fn iter<'a>(&'a self) -> Self::Iter<'a> {
-   |                                         ^^ lifetime parameter not allowed on this type
+   |                                         ^^ lifetime parameter not allowed
 
 error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/iterable.rs:43:41
    |
 LL |     fn iter<'a>(&'a self) -> Self::Iter<'a> {
-   |                                         ^^ lifetime parameter not allowed on this type
+   |                                         ^^ lifetime parameter not allowed
 
 error: aborting due to 6 previous errors
 
index df83fdaad5bfa66f13ce9210569fe1a31e288faf..c8d37a51fa96bd5cd73e1c6161a89c453bca1b62 100644 (file)
@@ -1,3 +1,9 @@
+error[E0110]: lifetime parameters are not allowed on this type
+  --> $DIR/parameter_number_and_kind.rs:26:27
+   |
+LL |     type FOk<T> = Self::E<'static, T>;
+   |                           ^^^^^^^ lifetime parameter not allowed
+
 error[E0109]: type parameters are not allowed on this type
   --> $DIR/parameter_number_and_kind.rs:26:36
    |
@@ -5,16 +11,16 @@ LL |     type FOk<T> = Self::E<'static, T>;
    |                                    ^ type parameter not allowed
 
 error[E0110]: lifetime parameters are not allowed on this type
-  --> $DIR/parameter_number_and_kind.rs:26:27
+  --> $DIR/parameter_number_and_kind.rs:29:26
    |
-LL |     type FOk<T> = Self::E<'static, T>;
-   |                           ^^^^^^^ lifetime parameter not allowed on this type
+LL |     type FErr1 = Self::E<'static, 'static>; // Error
+   |                          ^^^^^^^ lifetime parameter not allowed
 
 error[E0110]: lifetime parameters are not allowed on this type
-  --> $DIR/parameter_number_and_kind.rs:29:26
+  --> $DIR/parameter_number_and_kind.rs:31:29
    |
-LL |     type FErr1 = Self::E<'static, 'static>; // Error
-   |                          ^^^^^^^ lifetime parameter not allowed on this type
+LL |     type FErr2<T> = Self::E<'static, T, u32>; // Error
+   |                             ^^^^^^^ lifetime parameter not allowed
 
 error[E0109]: type parameters are not allowed on this type
   --> $DIR/parameter_number_and_kind.rs:31:38
@@ -22,12 +28,6 @@ error[E0109]: type parameters are not allowed on this type
 LL |     type FErr2<T> = Self::E<'static, T, u32>; // Error
    |                                      ^ type parameter not allowed
 
-error[E0110]: lifetime parameters are not allowed on this type
-  --> $DIR/parameter_number_and_kind.rs:31:29
-   |
-LL |     type FErr2<T> = Self::E<'static, T, u32>; // Error
-   |                             ^^^^^^^ lifetime parameter not allowed on this type
-
 error: aborting due to 5 previous errors
 
 Some errors occurred: E0109, E0110.
index 607a4b8d57996e1cb0343783c379a9e4669093c8..12e206cbd476af56a70098be716d39a69b699fc8 100644 (file)
@@ -2,31 +2,31 @@ error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/streaming_iterator.rs:27:41
    |
 LL |     bar: <T as StreamingIterator>::Item<'static>,
-   |                                         ^^^^^^^ lifetime parameter not allowed on this type
+   |                                         ^^^^^^^ lifetime parameter not allowed
 
 error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/streaming_iterator.rs:35:64
    |
 LL | fn foo<T>(iter: T) where T: StreamingIterator, for<'a> T::Item<'a>: Display { /* ... */ }
-   |                                                                ^^ lifetime parameter not allowed on this type
+   |                                                                ^^ lifetime parameter not allowed
 
 error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/streaming_iterator.rs:21:48
    |
 LL |     fn next<'a>(&'a self) -> Option<Self::Item<'a>>;
-   |                                                ^^ lifetime parameter not allowed on this type
+   |                                                ^^ lifetime parameter not allowed
 
 error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/streaming_iterator.rs:47:37
    |
 LL |     type Item<'a> = (usize, I::Item<'a>);
-   |                                     ^^ lifetime parameter not allowed on this type
+   |                                     ^^ lifetime parameter not allowed
 
 error[E0110]: lifetime parameters are not allowed on this type
   --> $DIR/streaming_iterator.rs:49:48
    |
 LL |     fn next<'a>(&'a self) -> Option<Self::Item<'a>> {
-   |                                                ^^ lifetime parameter not allowed on this type
+   |                                                ^^ lifetime parameter not allowed
 
 error: aborting due to 5 previous errors
 
index 6b8417bf9db6d8b131ff6479fdb787b195f20f2e..6fd2b320472f3cd5c623906ff208d2cbf995ec49 100644 (file)
@@ -2,7 +2,9 @@ error: lifetime parameter `'a` only used once
   --> $DIR/fn-types.rs:19:10
    |
 LL |   a: for<'a> fn(&'a u32), //~ ERROR `'a` only used once
-   |          ^^
+   |          ^^      -- ...is used only here
+   |          |
+   |          this lifetime...
    |
 note: lint level defined here
   --> $DIR/fn-types.rs:11:9
index 3694c2452f34c0ecb810728cea63d099a5a2c4fe..3dd2675646cde0918112259118a93d20b61ee72f 100644 (file)
@@ -3,6 +3,9 @@ error: lifetime parameter `'b` only used once
    |
 LL | fn a(x: &'a u32, y: &'b u32) {
    |                      ^^
+   |                      |
+   |                      this lifetime...
+   |                      ...is used only here
    |
 note: lint level defined here
   --> $DIR/one-use-in-fn-argument-in-band.rs:12:9
@@ -15,6 +18,9 @@ error: lifetime parameter `'a` only used once
    |
 LL | fn a(x: &'a u32, y: &'b u32) {
    |          ^^
+   |          |
+   |          this lifetime...
+   |          ...is used only here
 
 error: aborting due to 2 previous errors
 
index f1304568fe72cb6a32b32642191eb77cd8cc3ab4..4c13133581bb4d156433031f8ce36404b257a6d1 100644 (file)
@@ -2,7 +2,9 @@ error: lifetime parameter `'a` only used once
   --> $DIR/one-use-in-fn-argument.rs:18:6
    |
 LL | fn a<'a>(x: &'a u32) { //~ ERROR `'a` only used once
-   |      ^^
+   |      ^^      -- ...is used only here
+   |      |
+   |      this lifetime...
    |
 note: lint level defined here
   --> $DIR/one-use-in-fn-argument.rs:11:9
index 8f91ca0ce54c32a27899ea479c1725c7c614faa2..2509366f9696fb080dbe1d2b21b5740c89d51e9b 100644 (file)
@@ -2,7 +2,9 @@ error: lifetime parameter `'f` only used once
   --> $DIR/one-use-in-inherent-impl-header.rs:24:6
    |
 LL | impl<'f> Foo<'f> { //~ ERROR `'f` only used once
-   |      ^^
+   |      ^^      -- ...is used only here
+   |      |
+   |      this lifetime...
    |
 note: lint level defined here
   --> $DIR/one-use-in-inherent-impl-header.rs:11:9
index 4811a65ced91975849b5ffc96f30fd4cfb301f4a..cfc8dbf18dc01d02c07045acf6eeacad050a748e 100644 (file)
@@ -2,7 +2,9 @@ error: lifetime parameter `'a` only used once
   --> $DIR/one-use-in-inherent-method-argument.rs:22:19
    |
 LL |     fn inherent_a<'a>(&self, data: &'a u32) { //~ ERROR `'a` only used once
-   |                   ^^
+   |                   ^^                -- ...is used only here
+   |                   |
+   |                   this lifetime...
    |
 note: lint level defined here
   --> $DIR/one-use-in-inherent-method-argument.rs:11:9
@@ -14,7 +16,9 @@ error: lifetime parameter `'f` only used once
   --> $DIR/one-use-in-inherent-method-argument.rs:21:6
    |
 LL | impl<'f> Foo<'f> { //~ ERROR `'f` only used once
-   |      ^^
+   |      ^^      -- ...is used only here
+   |      |
+   |      this lifetime...
 
 error: aborting due to 2 previous errors
 
index b552c8475d8900800ddabc0a77f1581c6277325e..8aa19d4e3ee916e7c1e9c463ea16e9ab6b30ad56 100644 (file)
@@ -2,7 +2,9 @@ error: lifetime parameter `'f` only used once
   --> $DIR/one-use-in-inherent-method-return.rs:22:6
    |
 LL | impl<'f> Foo<'f> { //~ ERROR `'f` only used once
-   |      ^^
+   |      ^^      -- ...is used only here
+   |      |
+   |      this lifetime...
    |
 note: lint level defined here
   --> $DIR/one-use-in-inherent-method-return.rs:11:9
index de74800ff60140a2aa97b15e241d6f804dd27b0e..4a796d83242fd91570718d2a72c8e77b8ecf5bae 100644 (file)
@@ -2,7 +2,9 @@ error: lifetime parameter `'g` only used once
   --> $DIR/one-use-in-trait-method-argument.rs:25:13
    |
 LL |     fn next<'g>(&'g mut self) -> Option<Self::Item> { //~ ERROR `'g` only used once
-   |             ^^
+   |             ^^   -- ...is used only here
+   |             |
+   |             this lifetime...
    |
 note: lint level defined here
   --> $DIR/one-use-in-trait-method-argument.rs:14:9
index ca0b050b696793dca7c44879adc245fcf3ed885a..b4b370d6e976b81645c8b8c409da752da3579674 100644 (file)
@@ -2,7 +2,9 @@ error: lifetime parameter `'f` only used once
   --> $DIR/two-uses-in-inherent-method-argument-and-return.rs:22:6
    |
 LL | impl<'f> Foo<'f> { //~ ERROR `'f` only used once
-   |      ^^
+   |      ^^      -- ...is used only here
+   |      |
+   |      this lifetime...
    |
 note: lint level defined here
   --> $DIR/two-uses-in-inherent-method-argument-and-return.rs:14:9
index cf615eed55691d3fc1db747ee184707042d3c7b8..b318e778f8766b6c78f3d23290252a2bbdf67a3e 100644 (file)
@@ -2,7 +2,7 @@ error[E0596]: cannot borrow immutable item `*x` as mutable
   --> $DIR/borrowck-object-mutability.rs:19:5
    |
 LL | fn borrowed_receiver(x: &Foo) {
-   |                         ---- help: consider changing this to be a mutable reference: `&mut Foo`
+   |                         ---- help: consider changing this to be a mutable reference: `&mut dyn Foo`
 LL |     x.borrowed();
 LL |     x.borrowed_mut(); //~ ERROR cannot borrow
    |     ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
diff --git a/src/test/ui/struct-duplicate-comma.rs b/src/test/ui/struct-duplicate-comma.rs
new file mode 100644 (file)
index 0000000..d7ee2f2
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -Z parse-only
+
+// Issue #50974
+
+struct Foo {
+    a: u8,
+    b: u8
+}
+
+fn main() {
+    let bar = Foo {
+        a: 0,,
+          //~^ ERROR expected identifier
+        b: 42
+    };
+}
+
diff --git a/src/test/ui/struct-duplicate-comma.stderr b/src/test/ui/struct-duplicate-comma.stderr
new file mode 100644 (file)
index 0000000..06e3b95
--- /dev/null
@@ -0,0 +1,13 @@
+error: expected identifier, found `,`
+  --> $DIR/struct-duplicate-comma.rs:22:14
+   |
+LL |     let bar = Foo {
+   |               --- while parsing this struct
+LL |         a: 0,,
+   |              ^
+   |              |
+   |              expected identifier
+   |              help: remove this comma
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/suggestions/auxiliary/macro-in-other-crate.rs b/src/test/ui/suggestions/auxiliary/macro-in-other-crate.rs
new file mode 100644 (file)
index 0000000..01282f2
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[macro_export]
+macro_rules! mac {
+    ($ident:ident) => { let $ident = 42; }
+}
index bd5efcd9fee7a756c81f25cee7e1804599eb3105..9049ffd40909007a94d56a40f5d664da56753e1c 100644 (file)
@@ -75,7 +75,7 @@ LL |     w.wrap.not_closure();
    |
    = help: did you mean to write `w.wrap.not_closure` instead of `w.wrap.not_closure(...)`?
 
-error[E0599]: no method named `closure` found for type `Obj<std::boxed::Box<std::boxed::FnBox<(), Output=u32> + 'static>>` in the current scope
+error[E0599]: no method named `closure` found for type `Obj<std::boxed::Box<(dyn std::boxed::FnBox<(), Output=u32> + 'static)>>` in the current scope
   --> $DIR/issue-2392.rs:72:24
    |
 LL | struct Obj<F> where F: FnOnce() -> u32 {
diff --git a/src/test/ui/suggestions/dotdotdot-expr.rs b/src/test/ui/suggestions/dotdotdot-expr.rs
new file mode 100644 (file)
index 0000000..afb73a5
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let _redemptive = 1...21;
+    //~^ ERROR unexpected token
+}
diff --git a/src/test/ui/suggestions/dotdotdot-expr.stderr b/src/test/ui/suggestions/dotdotdot-expr.stderr
new file mode 100644 (file)
index 0000000..3315538
--- /dev/null
@@ -0,0 +1,16 @@
+error: unexpected token: `...`
+  --> $DIR/dotdotdot-expr.rs:12:24
+   |
+LL |     let _redemptive = 1...21;
+   |                        ^^^
+help: use `..` for an exclusive range
+   |
+LL |     let _redemptive = 1..21;
+   |                        ^^
+help: or `..=` for an inclusive range
+   |
+LL |     let _redemptive = 1..=21;
+   |                        ^^^
+
+error: aborting due to previous error
+
index 9bf74c3875fed5f379d35372a1baea0db62d2ec2..2b6e830ec59622f871a177d317dea34d461aa2e9 100644 (file)
@@ -8,11 +8,35 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// aux-build:macro-in-other-crate.rs
+
+#[macro_use] extern crate macro_in_other_crate;
+
+macro_rules! local_mac {
+    ($ident:ident) => { let $ident = 42; }
+}
+
 fn main() {
     let x = 2.0.neg();
     //~^ ERROR can't call method `neg` on ambiguous numeric type `{float}`
+
     let y = 2.0;
     let x = y.neg();
     //~^ ERROR can't call method `neg` on ambiguous numeric type `{float}`
     println!("{:?}", x);
+
+    for i in 0..100 {
+        println!("{}", i.pow(2));
+        //~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}`
+    }
+
+    local_mac!(local_bar);
+    local_bar.pow(2);
+    //~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}`
+}
+
+fn qux() {
+    mac!(bar);
+    bar.pow(2);
+    //~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}`
 }
index 68c8be7dff8c941de2164d31a72574735a55e3b6..796520e0ec71ba3849cb37fba9c756d9ff5d9c29 100644 (file)
@@ -1,5 +1,5 @@
 error[E0689]: can't call method `neg` on ambiguous numeric type `{float}`
-  --> $DIR/method-on-ambiguous-numeric-type.rs:12:17
+  --> $DIR/method-on-ambiguous-numeric-type.rs:20:17
    |
 LL |     let x = 2.0.neg();
    |                 ^^^
@@ -9,7 +9,7 @@ LL |     let x = 2.0_f32.neg();
    |             ^^^^^^^
 
 error[E0689]: can't call method `neg` on ambiguous numeric type `{float}`
-  --> $DIR/method-on-ambiguous-numeric-type.rs:15:15
+  --> $DIR/method-on-ambiguous-numeric-type.rs:24:15
    |
 LL |     let x = y.neg();
    |               ^^^
@@ -18,6 +18,34 @@ help: you must specify a type for this binding, like `f32`
 LL |     let y: f32 = 2.0;
    |         ^^^^^^
 
-error: aborting due to 2 previous errors
+error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}`
+  --> $DIR/method-on-ambiguous-numeric-type.rs:29:26
+   |
+LL |     for i in 0..100 {
+   |         - you must specify a type for this binding, like `i32`
+LL |         println!("{}", i.pow(2));
+   |                          ^^^
+
+error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}`
+  --> $DIR/method-on-ambiguous-numeric-type.rs:34:15
+   |
+LL |     local_bar.pow(2);
+   |               ^^^
+help: you must specify a type for this binding, like `i32`
+   |
+LL |     ($ident:ident) => { let $ident: i32 = 42; }
+   |                             ^^^^^^^^^^^
+
+error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}`
+  --> $DIR/method-on-ambiguous-numeric-type.rs:40:9
+   |
+LL |     mac!(bar);
+   |     ---------- you must specify a type for this binding, like `i32`
+LL |     bar.pow(2);
+   |         ^^^
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0689`.
index b70028bd926c6ea78c2fe27eb4f55c2cddd98c4f..8fbab4022327171feb87ce682c25b0f7d3154273 100644 (file)
@@ -15,7 +15,7 @@ fn main() {
   let u: &str = if true { s[..2] } else { s };
   //~^ ERROR mismatched types
   let v = s[..2];
-  //~^ ERROR the trait bound `str: std::marker::Sized` is not satisfied
+  //~^ ERROR the size for value values of type
   let w: &str = s[..2];
   //~^ ERROR mismatched types
 }
index 76db882742a01a331e9a0cfe01ab3294ff44d344..12699d8b25f81750393da26779a59a5d70d020e1 100644 (file)
@@ -19,15 +19,16 @@ LL |   let u: &str = if true { s[..2] } else { s };
    = note: expected type `&str`
               found type `str`
 
-error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
+error[E0277]: the size for value values of type `str` cannot be known at compilation time
   --> $DIR/str-array-assignment.rs:17:7
    |
 LL |   let v = s[..2];
    |       ^   ------ help: consider borrowing here: `&s[..2]`
    |       |
-   |       `str` does not have a constant size known at compile-time
+   |       doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `str`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: all local variables must have a statically known size
 
 error[E0308]: mismatched types
index b56b95a8aafd796852fbeee7c699913c6fe4f4ff..84dbc7ffc2f8f50826e597f4aacf69b5b254d43d 100644 (file)
@@ -1,8 +1,8 @@
-error: expected one of `(`, `const`, `default`, `extern`, `fn`, `type`, or `unsafe`, found `}`
+error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `type`, or `unsafe`, found `}`
   --> $DIR/issue-41155.rs:13:1
    |
 LL |     pub
-   |        - expected one of 7 possible tokens here
+   |        - expected one of 8 possible tokens here
 LL | } //~ ERROR expected one of
    | ^ unexpected token
 
index 5dcb4c8a220baf865e59ff4d6f70585d43d94e18..dd74f4f4797272400bc36dd0bd7f6dd9ccee42d0 100644 (file)
 fn check<T: Iterator, U: ?Sized>() {
     // suggest a where-clause, if needed
     mem::size_of::<U>();
-    //~^ ERROR `U: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 
     mem::size_of::<Misc<U>>();
-    //~^ ERROR `U: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 
     // ... even if T occurs as a type parameter
 
@@ -36,10 +36,10 @@ fn check<T: Iterator, U: ?Sized>() {
     // ... and also not if the error is not related to the type
 
     mem::size_of::<[T]>();
-    //~^ ERROR `[T]: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 
     mem::size_of::<[&U]>();
-    //~^ ERROR `[&U]: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
 
 fn main() {
index abd9f5a8b73f77a758d3539f481355bccaf1c83f..feb31ae22d8ca9b01fc81c982287d6b0c01ed4a9 100644 (file)
@@ -1,20 +1,22 @@
-error[E0277]: the trait bound `U: std::marker::Sized` is not satisfied
+error[E0277]: the size for value values of type `U` cannot be known at compilation time
   --> $DIR/trait-suggest-where-clause.rs:17:5
    |
 LL |     mem::size_of::<U>();
-   |     ^^^^^^^^^^^^^^^^^ `U` does not have a constant size known at compile-time
+   |     ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `U`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = help: consider adding a `where U: std::marker::Sized` bound
    = note: required by `std::mem::size_of`
 
-error[E0277]: the trait bound `U: std::marker::Sized` is not satisfied in `Misc<U>`
+error[E0277]: the size for value values of type `U` cannot be known at compilation time
   --> $DIR/trait-suggest-where-clause.rs:20:5
    |
 LL |     mem::size_of::<Misc<U>>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ `U` does not have a constant size known at compile-time
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `Misc<U>`, the trait `std::marker::Sized` is not implemented for `U`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = help: consider adding a `where U: std::marker::Sized` bound
    = note: required because it appears within the type `Misc<U>`
    = note: required by `std::mem::size_of`
@@ -45,22 +47,24 @@ LL |     <Misc<_> as From<T>>::from;
    |
    = note: required by `std::convert::From::from`
 
-error[E0277]: the trait bound `[T]: std::marker::Sized` is not satisfied
+error[E0277]: the size for value values of type `[T]` cannot be known at compilation time
   --> $DIR/trait-suggest-where-clause.rs:38:5
    |
 LL |     mem::size_of::<[T]>();
-   |     ^^^^^^^^^^^^^^^^^^^ `[T]` does not have a constant size known at compile-time
+   |     ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `[T]`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: required by `std::mem::size_of`
 
-error[E0277]: the trait bound `[&U]: std::marker::Sized` is not satisfied
+error[E0277]: the size for value values of type `[&U]` cannot be known at compilation time
   --> $DIR/trait-suggest-where-clause.rs:41:5
    |
 LL |     mem::size_of::<[&U]>();
-   |     ^^^^^^^^^^^^^^^^^^^^ `[&U]` does not have a constant size known at compile-time
+   |     ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `[&U]`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: required by `std::mem::size_of`
 
 error: aborting due to 7 previous errors
index ee2ff7d7861396d5353f2b5e9817e1ca389b2fd1..e18018c6f0c0172a074abe4e32b98f6034df6591 100644 (file)
@@ -6,7 +6,7 @@ LL | struct S(str, str) where str: Sized;
    |
    = note: #[warn(trivial_bounds)] on by default
 
-warning: Trait bound for<'a> T<A + 'a>: std::marker::Sized does not depend on any type or lifetime parameters
+warning: Trait bound for<'a> T<(dyn A + 'a)>: std::marker::Sized does not depend on any type or lifetime parameters
   --> $DIR/trivial-bounds-inconsistent-sized.rs:26:1
    |
 LL | / fn unsized_local() where for<'a> T<A + 'a>: Sized {
index ee3c7518294773e9dfee69b672440a4c2cbee720..85b16b17042f640862c23da564c98a017d038434 100644 (file)
@@ -78,7 +78,7 @@ warning: Trait bound str: std::marker::Sized does not depend on any type or life
 LL | struct TwoStrs(str, str) where str: Sized;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: Trait bound for<'a> Dst<A + 'a>: std::marker::Sized does not depend on any type or lifetime parameters
+warning: Trait bound for<'a> Dst<(dyn A + 'a)>: std::marker::Sized does not depend on any type or lifetime parameters
   --> $DIR/trivial-bounds-inconsistent.rs:65:1
    |
 LL | / fn unsized_local() where for<'a> Dst<A + 'a>: Sized {
index df91ba0dd2ac5b2b6513be46ab98f5a5b9909f3d..d08574c3d878967d533fd7c36f6a4b5f8e1547fb 100644 (file)
@@ -1,10 +1,11 @@
-error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
+error[E0277]: the size for value values of type `str` cannot be known at compilation time
   --> $DIR/trivial-bounds-leak.rs:22:25
    |
 LL | fn cant_return_str() -> str { //~ ERROR
-   |                         ^^^ `str` does not have a constant size known at compile-time
+   |                         ^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `str`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: the return type of a function must have a statically known size
 
 error[E0599]: no method named `test` found for type `i32` in the current scope
index f916df5d32d0462826035a9e87aca7351c6ee88e..92a45db0689680e81b63a003e3200ae583f79eb5 100644 (file)
 
 struct Foo<T, U: FromIterator<T>>(T, U);
 struct WellFormed<Z = Foo<i32, i32>>(Z);
-//~^ error: the trait bound `i32: std::iter::FromIterator<i32>` is not satisfied [E0277]
+//~^ ERROR a collection of type `i32` cannot be built from an iterator over elements of type `i32`
 struct WellFormedNoBounds<Z:?Sized = Foo<i32, i32>>(Z);
-//~^ error: the trait bound `i32: std::iter::FromIterator<i32>` is not satisfied [E0277]
+//~^ ERROR a collection of type `i32` cannot be built from an iterator over elements of type `i32`
 
 struct Bounds<T:Copy=String>(T);
-//~^ error: the trait bound `std::string::String: std::marker::Copy` is not satisfied [E0277]
+//~^ ERROR the trait bound `std::string::String: std::marker::Copy` is not satisfied [E0277]
 
 struct WhereClause<T=String>(T) where T: Copy;
-//~^ error: the trait bound `std::string::String: std::marker::Copy` is not satisfied [E0277]
+//~^ ERROR the trait bound `std::string::String: std::marker::Copy` is not satisfied [E0277]
 
 trait TraitBound<T:Copy=String> {}
-//~^ error: the trait bound `std::string::String: std::marker::Copy` is not satisfied [E0277]
+//~^ ERROR the trait bound `std::string::String: std::marker::Copy` is not satisfied [E0277]
 
 trait Super<T: Copy> { }
 trait Base<T = String>: Super<T> { }
-//~^ error: the trait bound `T: std::marker::Copy` is not satisfied [E0277]
+//~^ ERROR the trait bound `T: std::marker::Copy` is not satisfied [E0277]
 
 trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {}
-//~^ error:  cannot add `u8` to `i32` [E0277]
+//~^ ERROR cannot add `u8` to `i32` [E0277]
 
 fn main() { }
index a2d6e53df050236ac5be1dd64bb75f0486bef485..aa124110243a52cc6cdb67cedb742d45237a8843 100644 (file)
@@ -1,8 +1,8 @@
-error[E0277]: the trait bound `i32: std::iter::FromIterator<i32>` is not satisfied
+error[E0277]: a collection of type `i32` cannot be built from an iterator over elements of type `i32`
   --> $DIR/type-check-defaults.rs:16:19
    |
 LL | struct WellFormed<Z = Foo<i32, i32>>(Z);
-   |                   ^ a collection of type `i32` cannot be built from an iterator over elements of type `i32`
+   |                   ^ a collection of type `i32` cannot be built from `std::iter::Iterator<Item=i32>`
    |
    = help: the trait `std::iter::FromIterator<i32>` is not implemented for `i32`
 note: required by `Foo`
@@ -11,11 +11,11 @@ note: required by `Foo`
 LL | struct Foo<T, U: FromIterator<T>>(T, U);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0277]: the trait bound `i32: std::iter::FromIterator<i32>` is not satisfied
+error[E0277]: a collection of type `i32` cannot be built from an iterator over elements of type `i32`
   --> $DIR/type-check-defaults.rs:18:27
    |
 LL | struct WellFormedNoBounds<Z:?Sized = Foo<i32, i32>>(Z);
-   |                           ^ a collection of type `i32` cannot be built from an iterator over elements of type `i32`
+   |                           ^ a collection of type `i32` cannot be built from `std::iter::Iterator<Item=i32>`
    |
    = help: the trait `std::iter::FromIterator<i32>` is not implemented for `i32`
 note: required by `Foo`
index 98249d3f2b567cbfac23e87ff46a620e8dc97b8c..cb545ca008d6581f503d6360ece9a41723367cfc 100644 (file)
@@ -19,8 +19,8 @@ LL |     Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
    |              ^^^^^
    = note: but, the lifetime must be valid for the static lifetime...
    = note: ...so that the expression is assignable:
-           expected std::boxed::Box<std::iter::Iterator<Item=&T> + 'static>
-              found std::boxed::Box<std::iter::Iterator<Item=&T>>
+           expected std::boxed::Box<(dyn std::iter::Iterator<Item=&T> + 'static)>
+              found std::boxed::Box<dyn std::iter::Iterator<Item=&T>>
 
 error: aborting due to previous error
 
index 8999f1e0930bed3898474fda10a779ebf4704321..15822ae42998c5769acd0670067bdaba22396ed1 100644 (file)
 #![feature(untagged_unions)]
 
 union Foo<T: ?Sized> {
-    value: T, //~ ERROR the trait bound `T: std::marker::Sized` is not satisfied
+    value: T,
+    //~^ ERROR the size for value values of type
 }
 
 struct Foo2<T: ?Sized> {
-    value: T, //~ ERROR the trait bound `T: std::marker::Sized` is not satisfied
+    value: T,
+    //~^ ERROR the size for value values of type
     t: u32,
 }
 
 enum Foo3<T: ?Sized> {
-    Value(T), //~ ERROR the trait bound `T: std::marker::Sized` is not satisfied
+    Value(T),
+    //~^ ERROR the size for value values of type
 }
 
 fn main() {}
index ba80af6c7e037b7739310d06d14d04b020092b8d..c6b7cf4e078233c5bc6cdb86696ddc5856d01e97 100644 (file)
@@ -1,30 +1,33 @@
-error[E0277]: the trait bound `T: std::marker::Sized` is not satisfied
+error[E0277]: the size for value values of type `T` cannot be known at compilation time
   --> $DIR/union-sized-field.rs:14:5
    |
-LL |     value: T, //~ ERROR the trait bound `T: std::marker::Sized` is not satisfied
-   |     ^^^^^^^^ `T` does not have a constant size known at compile-time
+LL |     value: T,
+   |     ^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `T`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = help: consider adding a `where T: std::marker::Sized` bound
    = note: no field of a union may have a dynamically sized type
 
-error[E0277]: the trait bound `T: std::marker::Sized` is not satisfied
-  --> $DIR/union-sized-field.rs:18:5
+error[E0277]: the size for value values of type `T` cannot be known at compilation time
+  --> $DIR/union-sized-field.rs:19:5
    |
-LL |     value: T, //~ ERROR the trait bound `T: std::marker::Sized` is not satisfied
-   |     ^^^^^^^^ `T` does not have a constant size known at compile-time
+LL |     value: T,
+   |     ^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `T`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = help: consider adding a `where T: std::marker::Sized` bound
    = note: only the last field of a struct may have a dynamically sized type
 
-error[E0277]: the trait bound `T: std::marker::Sized` is not satisfied
-  --> $DIR/union-sized-field.rs:23:11
+error[E0277]: the size for value values of type `T` cannot be known at compilation time
+  --> $DIR/union-sized-field.rs:25:11
    |
-LL |     Value(T), //~ ERROR the trait bound `T: std::marker::Sized` is not satisfied
-   |           ^ `T` does not have a constant size known at compile-time
+LL |     Value(T),
+   |           ^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `T`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = help: consider adding a `where T: std::marker::Sized` bound
    = note: no field of an enum variant may have a dynamically sized type
 
index 95fc3243fbed34629eb516bc9f6799b4c32cef1b..9082ea4abddbdd669ad4a3c86539e84c83ee33fd 100644 (file)
@@ -30,37 +30,54 @@ trait PathHelper4 {}
 
 enum E<W: ?Sized, X: ?Sized, Y: ?Sized, Z: ?Sized> {
     // parameter
-    VA(W), //~ ERROR `W: std::marker::Sized` is not satisfied
-    VB{x: X}, //~ ERROR `X: std::marker::Sized` is not satisfied
-    VC(isize, Y), //~ ERROR `Y: std::marker::Sized` is not satisfied
-    VD{u: isize, x: Z}, //~ ERROR `Z: std::marker::Sized` is not satisfied
+    VA(W),
+    //~^ ERROR the size for value values of type
+    VB{x: X},
+    //~^ ERROR the size for value values of type
+    VC(isize, Y),
+    //~^ ERROR the size for value values of type
+    VD{u: isize, x: Z},
+    //~^ ERROR the size for value values of type
 
     // slice / str
-    VE([u8]), //~ ERROR `[u8]: std::marker::Sized` is not satisfied
-    VF{x: str}, //~ ERROR `str: std::marker::Sized` is not satisfied
-    VG(isize, [f32]), //~ ERROR `[f32]: std::marker::Sized` is not satisfied
-    VH{u: isize, x: [u32]}, //~ ERROR `[u32]: std::marker::Sized` is not satisfied
+    VE([u8]),
+    //~^ ERROR the size for value values of type
+    VF{x: str},
+    //~^ ERROR the size for value values of type
+    VG(isize, [f32]),
+    //~^ ERROR the size for value values of type
+    VH{u: isize, x: [u32]},
+    //~^ ERROR the size for value values of type
 
     // unsized struct
-    VI(Path1), //~ ERROR `PathHelper1 + 'static: std::marker::Sized` is not satisfied
-    VJ{x: Path2}, //~ ERROR `PathHelper2 + 'static: std::marker::Sized` is not satisfied
-    VK(isize, Path3), //~ ERROR `PathHelper3 + 'static: std::marker::Sized` is not satisfied
-    VL{u: isize, x: Path4}, //~ ERROR `PathHelper4 + 'static: std::marker::Sized` is not satisfied
+    VI(Path1),
+    //~^ ERROR the size for value values of type
+    VJ{x: Path2},
+    //~^ ERROR the size for value values of type
+    VK(isize, Path3),
+    //~^ ERROR the size for value values of type
+    VL{u: isize, x: Path4},
+    //~^ ERROR the size for value values of type
 
     // plain trait
-    VM(Foo),  //~ ERROR `Foo + 'static: std::marker::Sized` is not satisfied
-    VN{x: Bar}, //~ ERROR `Bar + 'static: std::marker::Sized` is not satisfied
-    VO(isize, FooBar), //~ ERROR `FooBar + 'static: std::marker::Sized` is not satisfied
-    VP{u: isize, x: BarFoo}, //~ ERROR `BarFoo + 'static: std::marker::Sized` is not satisfied
+    VM(Foo),
+    //~^ ERROR the size for value values of type
+    VN{x: Bar},
+    //~^ ERROR the size for value values of type
+    VO(isize, FooBar),
+    //~^ ERROR the size for value values of type
+    VP{u: isize, x: BarFoo},
+    //~^ ERROR the size for value values of type
 
     // projected
-    VQ(<&'static [i8] as Deref>::Target), //~ ERROR `[i8]: std::marker::Sized` is not satisfied
+    VQ(<&'static [i8] as Deref>::Target),
+    //~^ ERROR the size for value values of type
     VR{x: <&'static [char] as Deref>::Target},
-    //~^ ERROR `[char]: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
     VS(isize, <&'static [f64] as Deref>::Target),
-    //~^ ERROR `[f64]: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
     VT{u: isize, x: <&'static [i32] as Deref>::Target},
-    //~^ ERROR `[i32]: std::marker::Sized` is not satisfied
+    //~^ ERROR the size for value values of type
 }
 
 
index 0e18efbf9da3eda5b87c4e8d72e1e123bca283e8..1f30c815d30a8be7bba90b1ecee850bfa4bddff6 100644 (file)
-error[E0277]: the trait bound `W: std::marker::Sized` is not satisfied
+error[E0277]: the size for value values of type `W` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:33:8
    |
-LL |     VA(W), //~ ERROR `W: std::marker::Sized` is not satisfied
-   |        ^ `W` does not have a constant size known at compile-time
+LL |     VA(W),
+   |        ^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `W`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = help: consider adding a `where W: std::marker::Sized` bound
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `X: std::marker::Sized` is not satisfied
-  --> $DIR/unsized-enum2.rs:34:8
+error[E0277]: the size for value values of type `X` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:35:8
    |
-LL |     VB{x: X}, //~ ERROR `X: std::marker::Sized` is not satisfied
-   |        ^^^^ `X` does not have a constant size known at compile-time
+LL |     VB{x: X},
+   |        ^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `X`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = help: consider adding a `where X: std::marker::Sized` bound
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `Y: std::marker::Sized` is not satisfied
-  --> $DIR/unsized-enum2.rs:35:15
+error[E0277]: the size for value values of type `Y` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:37:15
    |
-LL |     VC(isize, Y), //~ ERROR `Y: std::marker::Sized` is not satisfied
-   |               ^ `Y` does not have a constant size known at compile-time
+LL |     VC(isize, Y),
+   |               ^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `Y`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = help: consider adding a `where Y: std::marker::Sized` bound
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `Z: std::marker::Sized` is not satisfied
-  --> $DIR/unsized-enum2.rs:36:18
+error[E0277]: the size for value values of type `Z` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:39:18
    |
-LL |     VD{u: isize, x: Z}, //~ ERROR `Z: std::marker::Sized` is not satisfied
-   |                  ^^^^ `Z` does not have a constant size known at compile-time
+LL |     VD{u: isize, x: Z},
+   |                  ^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `Z`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = help: consider adding a `where Z: std::marker::Sized` bound
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `[u8]: std::marker::Sized` is not satisfied
-  --> $DIR/unsized-enum2.rs:39:8
+error[E0277]: the size for value values of type `[u8]` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:43:8
    |
-LL |     VE([u8]), //~ ERROR `[u8]: std::marker::Sized` is not satisfied
-   |        ^^^^ `[u8]` does not have a constant size known at compile-time
+LL |     VE([u8]),
+   |        ^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `[u8]`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
-  --> $DIR/unsized-enum2.rs:40:8
+error[E0277]: the size for value values of type `str` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:45:8
    |
-LL |     VF{x: str}, //~ ERROR `str: std::marker::Sized` is not satisfied
-   |        ^^^^^^ `str` does not have a constant size known at compile-time
+LL |     VF{x: str},
+   |        ^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `str`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `[f32]: std::marker::Sized` is not satisfied
-  --> $DIR/unsized-enum2.rs:41:15
+error[E0277]: the size for value values of type `[f32]` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:47:15
    |
-LL |     VG(isize, [f32]), //~ ERROR `[f32]: std::marker::Sized` is not satisfied
-   |               ^^^^^ `[f32]` does not have a constant size known at compile-time
+LL |     VG(isize, [f32]),
+   |               ^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `[f32]`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `[u32]: std::marker::Sized` is not satisfied
-  --> $DIR/unsized-enum2.rs:42:18
+error[E0277]: the size for value values of type `[u32]` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:49:18
    |
-LL |     VH{u: isize, x: [u32]}, //~ ERROR `[u32]: std::marker::Sized` is not satisfied
-   |                  ^^^^^^^^ `[u32]` does not have a constant size known at compile-time
+LL |     VH{u: isize, x: [u32]},
+   |                  ^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `[u32]`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `Foo + 'static: std::marker::Sized` is not satisfied
-  --> $DIR/unsized-enum2.rs:51:8
+error[E0277]: the size for value values of type `(dyn Foo + 'static)` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:63:8
    |
-LL |     VM(Foo),  //~ ERROR `Foo + 'static: std::marker::Sized` is not satisfied
-   |        ^^^ `Foo + 'static` does not have a constant size known at compile-time
+LL |     VM(Foo),
+   |        ^^^ doesn't have a size known at compile-time
    |
-   = help: the trait `std::marker::Sized` is not implemented for `Foo + 'static`
+   = help: the trait `std::marker::Sized` is not implemented for `(dyn Foo + 'static)`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `Bar + 'static: std::marker::Sized` is not satisfied
-  --> $DIR/unsized-enum2.rs:52:8
+error[E0277]: the size for value values of type `(dyn Bar + 'static)` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:65:8
    |
-LL |     VN{x: Bar}, //~ ERROR `Bar + 'static: std::marker::Sized` is not satisfied
-   |        ^^^^^^ `Bar + 'static` does not have a constant size known at compile-time
+LL |     VN{x: Bar},
+   |        ^^^^^^ doesn't have a size known at compile-time
    |
-   = help: the trait `std::marker::Sized` is not implemented for `Bar + 'static`
+   = help: the trait `std::marker::Sized` is not implemented for `(dyn Bar + 'static)`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `FooBar + 'static: std::marker::Sized` is not satisfied
-  --> $DIR/unsized-enum2.rs:53:15
+error[E0277]: the size for value values of type `(dyn FooBar + 'static)` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:67:15
    |
-LL |     VO(isize, FooBar), //~ ERROR `FooBar + 'static: std::marker::Sized` is not satisfied
-   |               ^^^^^^ `FooBar + 'static` does not have a constant size known at compile-time
+LL |     VO(isize, FooBar),
+   |               ^^^^^^ doesn't have a size known at compile-time
    |
-   = help: the trait `std::marker::Sized` is not implemented for `FooBar + 'static`
+   = help: the trait `std::marker::Sized` is not implemented for `(dyn FooBar + 'static)`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `BarFoo + 'static: std::marker::Sized` is not satisfied
-  --> $DIR/unsized-enum2.rs:54:18
+error[E0277]: the size for value values of type `(dyn BarFoo + 'static)` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:69:18
    |
-LL |     VP{u: isize, x: BarFoo}, //~ ERROR `BarFoo + 'static: std::marker::Sized` is not satisfied
-   |                  ^^^^^^^^^ `BarFoo + 'static` does not have a constant size known at compile-time
+LL |     VP{u: isize, x: BarFoo},
+   |                  ^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = help: the trait `std::marker::Sized` is not implemented for `BarFoo + 'static`
+   = help: the trait `std::marker::Sized` is not implemented for `(dyn BarFoo + 'static)`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `[i8]: std::marker::Sized` is not satisfied
-  --> $DIR/unsized-enum2.rs:57:8
+error[E0277]: the size for value values of type `[i8]` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:73:8
    |
-LL |     VQ(<&'static [i8] as Deref>::Target), //~ ERROR `[i8]: std::marker::Sized` is not satisfied
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `[i8]` does not have a constant size known at compile-time
+LL |     VQ(<&'static [i8] as Deref>::Target),
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `[i8]`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `[char]: std::marker::Sized` is not satisfied
-  --> $DIR/unsized-enum2.rs:58:8
+error[E0277]: the size for value values of type `[char]` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:75:8
    |
 LL |     VR{x: <&'static [char] as Deref>::Target},
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `[char]` does not have a constant size known at compile-time
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `[char]`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `[f64]: std::marker::Sized` is not satisfied
-  --> $DIR/unsized-enum2.rs:60:15
+error[E0277]: the size for value values of type `[f64]` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:77:15
    |
 LL |     VS(isize, <&'static [f64] as Deref>::Target),
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `[f64]` does not have a constant size known at compile-time
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `[f64]`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `[i32]: std::marker::Sized` is not satisfied
-  --> $DIR/unsized-enum2.rs:62:18
+error[E0277]: the size for value values of type `[i32]` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:79:18
    |
 LL |     VT{u: isize, x: <&'static [i32] as Deref>::Target},
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `[i32]` does not have a constant size known at compile-time
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `[i32]`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `PathHelper1 + 'static: std::marker::Sized` is not satisfied in `Path1`
-  --> $DIR/unsized-enum2.rs:45:8
+error[E0277]: the size for value values of type `(dyn PathHelper1 + 'static)` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:53:8
    |
-LL |     VI(Path1), //~ ERROR `PathHelper1 + 'static: std::marker::Sized` is not satisfied
-   |        ^^^^^ `PathHelper1 + 'static` does not have a constant size known at compile-time
+LL |     VI(Path1),
+   |        ^^^^^ doesn't have a size known at compile-time
    |
-   = help: within `Path1`, the trait `std::marker::Sized` is not implemented for `PathHelper1 + 'static`
+   = help: within `Path1`, the trait `std::marker::Sized` is not implemented for `(dyn PathHelper1 + 'static)`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: required because it appears within the type `Path1`
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `PathHelper2 + 'static: std::marker::Sized` is not satisfied in `Path2`
-  --> $DIR/unsized-enum2.rs:46:8
+error[E0277]: the size for value values of type `(dyn PathHelper2 + 'static)` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:55:8
    |
-LL |     VJ{x: Path2}, //~ ERROR `PathHelper2 + 'static: std::marker::Sized` is not satisfied
-   |        ^^^^^^^^ `PathHelper2 + 'static` does not have a constant size known at compile-time
+LL |     VJ{x: Path2},
+   |        ^^^^^^^^ doesn't have a size known at compile-time
    |
-   = help: within `Path2`, the trait `std::marker::Sized` is not implemented for `PathHelper2 + 'static`
+   = help: within `Path2`, the trait `std::marker::Sized` is not implemented for `(dyn PathHelper2 + 'static)`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: required because it appears within the type `Path2`
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `PathHelper3 + 'static: std::marker::Sized` is not satisfied in `Path3`
-  --> $DIR/unsized-enum2.rs:47:15
+error[E0277]: the size for value values of type `(dyn PathHelper3 + 'static)` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:57:15
    |
-LL |     VK(isize, Path3), //~ ERROR `PathHelper3 + 'static: std::marker::Sized` is not satisfied
-   |               ^^^^^ `PathHelper3 + 'static` does not have a constant size known at compile-time
+LL |     VK(isize, Path3),
+   |               ^^^^^ doesn't have a size known at compile-time
    |
-   = help: within `Path3`, the trait `std::marker::Sized` is not implemented for `PathHelper3 + 'static`
+   = help: within `Path3`, the trait `std::marker::Sized` is not implemented for `(dyn PathHelper3 + 'static)`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: required because it appears within the type `Path3`
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the trait bound `PathHelper4 + 'static: std::marker::Sized` is not satisfied in `Path4`
-  --> $DIR/unsized-enum2.rs:48:18
+error[E0277]: the size for value values of type `(dyn PathHelper4 + 'static)` cannot be known at compilation time
+  --> $DIR/unsized-enum2.rs:59:18
    |
-LL |     VL{u: isize, x: Path4}, //~ ERROR `PathHelper4 + 'static: std::marker::Sized` is not satisfied
-   |                  ^^^^^^^^ `PathHelper4 + 'static` does not have a constant size known at compile-time
+LL |     VL{u: isize, x: Path4},
+   |                  ^^^^^^^^ doesn't have a size known at compile-time
    |
-   = help: within `Path4`, the trait `std::marker::Sized` is not implemented for `PathHelper4 + 'static`
+   = help: within `Path4`, the trait `std::marker::Sized` is not implemented for `(dyn PathHelper4 + 'static)`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: required because it appears within the type `Path4`
    = note: no field of an enum variant may have a dynamically sized type
 
index 91a44fdd424fb12ff34b2298ce7a8b1e12828293..35fc2182313c95de4b4a65076a3741f4e7473038 100644 (file)
@@ -184,6 +184,7 @@ struct Builder {
     cargo_release: String,
     rls_release: String,
     rustfmt_release: String,
+    llvm_tools_release: String,
 
     input: PathBuf,
     output: PathBuf,
@@ -196,11 +197,13 @@ struct Builder {
     cargo_version: Option<String>,
     rls_version: Option<String>,
     rustfmt_version: Option<String>,
+    llvm_tools_version: Option<String>,
 
     rust_git_commit_hash: Option<String>,
     cargo_git_commit_hash: Option<String>,
     rls_git_commit_hash: Option<String>,
     rustfmt_git_commit_hash: Option<String>,
+    llvm_tools_git_commit_hash: Option<String>,
 }
 
 fn main() {
@@ -212,6 +215,7 @@ fn main() {
     let cargo_release = args.next().unwrap();
     let rls_release = args.next().unwrap();
     let rustfmt_release = args.next().unwrap();
+    let llvm_tools_release = args.next().unwrap();
     let s3_address = args.next().unwrap();
     let mut passphrase = String::new();
     t!(io::stdin().read_to_string(&mut passphrase));
@@ -221,6 +225,7 @@ fn main() {
         cargo_release,
         rls_release,
         rustfmt_release,
+        llvm_tools_release,
 
         input,
         output,
@@ -233,11 +238,13 @@ fn main() {
         cargo_version: None,
         rls_version: None,
         rustfmt_version: None,
+        llvm_tools_version: None,
 
         rust_git_commit_hash: None,
         cargo_git_commit_hash: None,
         rls_git_commit_hash: None,
         rustfmt_git_commit_hash: None,
+        llvm_tools_git_commit_hash: None,
     }.build();
 }
 
@@ -247,11 +254,14 @@ fn build(&mut self) {
         self.cargo_version = self.version("cargo", "x86_64-unknown-linux-gnu");
         self.rls_version = self.version("rls", "x86_64-unknown-linux-gnu");
         self.rustfmt_version = self.version("rustfmt", "x86_64-unknown-linux-gnu");
+        self.llvm_tools_version = self.version("llvm-tools", "x86_64-unknown-linux-gnu");
 
         self.rust_git_commit_hash = self.git_commit_hash("rust", "x86_64-unknown-linux-gnu");
         self.cargo_git_commit_hash = self.git_commit_hash("cargo", "x86_64-unknown-linux-gnu");
         self.rls_git_commit_hash = self.git_commit_hash("rls", "x86_64-unknown-linux-gnu");
         self.rustfmt_git_commit_hash = self.git_commit_hash("rustfmt", "x86_64-unknown-linux-gnu");
+        self.llvm_tools_git_commit_hash = self.git_commit_hash("llvm-tools",
+                                                               "x86_64-unknown-linux-gnu");
 
         self.digest_and_sign();
         let manifest = self.build_manifest();
@@ -288,9 +298,11 @@ fn build_manifest(&mut self) -> Manifest {
         self.package("rls-preview", &mut manifest.pkg, HOSTS);
         self.package("rustfmt-preview", &mut manifest.pkg, HOSTS);
         self.package("rust-analysis", &mut manifest.pkg, TARGETS);
+        self.package("llvm-tools", &mut manifest.pkg, TARGETS);
 
         let rls_present = manifest.pkg.contains_key("rls-preview");
         let rustfmt_present = manifest.pkg.contains_key("rustfmt-preview");
+        let llvm_tools_present = manifest.pkg.contains_key("llvm-tools");
 
         if rls_present {
             manifest.renames.insert("rls".to_owned(), Rename { to: "rls-preview".to_owned() });
@@ -345,6 +357,12 @@ fn build_manifest(&mut self) -> Manifest {
                     target: host.to_string(),
                 });
             }
+            if llvm_tools_present {
+                extensions.push(Component {
+                    pkg: "llvm-tools".to_string(),
+                    target: host.to_string(),
+                });
+            }
             extensions.push(Component {
                 pkg: "rust-analysis".to_string(),
                 target: host.to_string(),
@@ -454,6 +472,8 @@ fn filename(&self, component: &str, target: &str) -> String {
             format!("rls-{}-{}.tar.gz", self.rls_release, target)
         } else if component == "rustfmt" || component == "rustfmt-preview" {
             format!("rustfmt-{}-{}.tar.gz", self.rustfmt_release, target)
+        } else if component == "llvm_tools" {
+            format!("llvm-tools-{}-{}.tar.gz", self.llvm_tools_release, target)
         } else {
             format!("{}-{}-{}.tar.gz", component, self.rust_release, target)
         }
@@ -466,6 +486,8 @@ fn cached_version(&self, component: &str) -> &Option<String> {
             &self.rls_version
         } else if component == "rustfmt" || component == "rustfmt-preview" {
             &self.rustfmt_version
+        } else if component == "llvm-tools" {
+            &self.llvm_tools_version
         } else {
             &self.rust_version
         }
@@ -478,6 +500,8 @@ fn cached_git_commit_hash(&self, component: &str) -> &Option<String> {
             &self.rls_git_commit_hash
         } else if component == "rustfmt" || component == "rustfmt-preview" {
             &self.rustfmt_git_commit_hash
+        } else if component == "llvm-tools" {
+            &self.llvm_tools_git_commit_hash
         } else {
             &self.rust_git_commit_hash
         }
index 08da30d72c9abfff4d41f6f081e31fd2929b820d..87edd75ecf26c9084969f431bb5e363693a8a4ca 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 08da30d72c9abfff4d41f6f081e31fd2929b820d
+Subproject commit 87edd75ecf26c9084969f431bb5e363693a8a4ca