Bug 1302028 - part 6 - vendor libbindgen and associated libraries; r?gps draft
authorNathan Froyd <froydnj@mozilla.com>
Wed, 14 Dec 2016 08:52:13 -0500
changeset 453509 4d25f30115c84913c9d2389585f2048efd9be40e
parent 453508 47c6fb572b27dfb891bdce8ae0453980db2c0e9f
child 540490 416bff053d2327d646df13bf9e675f0bba90a2ad
push id39696
push userbmo:nfroyd@mozilla.com
push dateFri, 23 Dec 2016 18:35:18 +0000
reviewersgps
bugs1302028
milestone53.0a1
Bug 1302028 - part 6 - vendor libbindgen and associated libraries; r?gps Holy package changes, Batman! MozReview-Commit-ID: 9s5MksVIZBv
third_party/rust/aster/.cargo-checksum.json
third_party/rust/aster/.cargo-ok
third_party/rust/aster/Cargo.toml
third_party/rust/aster/src/arm.rs
third_party/rust/aster/src/attr.rs
third_party/rust/aster/src/block.rs
third_party/rust/aster/src/constant.rs
third_party/rust/aster/src/ctx.rs
third_party/rust/aster/src/expr.rs
third_party/rust/aster/src/fn_decl.rs
third_party/rust/aster/src/generics.rs
third_party/rust/aster/src/ident.rs
third_party/rust/aster/src/invoke.rs
third_party/rust/aster/src/item.rs
third_party/rust/aster/src/lib.rs
third_party/rust/aster/src/lifetime.rs
third_party/rust/aster/src/lit.rs
third_party/rust/aster/src/mac.rs
third_party/rust/aster/src/method.rs
third_party/rust/aster/src/name.rs
third_party/rust/aster/src/pat.rs
third_party/rust/aster/src/path.rs
third_party/rust/aster/src/qpath.rs
third_party/rust/aster/src/self_.rs
third_party/rust/aster/src/stmt.rs
third_party/rust/aster/src/str.rs
third_party/rust/aster/src/struct_field.rs
third_party/rust/aster/src/ty.rs
third_party/rust/aster/src/ty_param.rs
third_party/rust/aster/src/variant.rs
third_party/rust/aster/src/variant_data.rs
third_party/rust/aster/src/where_predicate.rs
third_party/rust/cexpr/.cargo-checksum.json
third_party/rust/cexpr/.cargo-ok
third_party/rust/cexpr/.gitignore
third_party/rust/cexpr/Cargo.toml
third_party/rust/cexpr/LICENSE-APACHE
third_party/rust/cexpr/LICENSE-MIT
third_party/rust/cexpr/src/expr.rs
third_party/rust/cexpr/src/lib.rs
third_party/rust/cexpr/src/literal.rs
third_party/rust/cexpr/src/token.rs
third_party/rust/cexpr/tests/clang.rs
third_party/rust/cexpr/tests/input/chars.h
third_party/rust/cexpr/tests/input/fail.h
third_party/rust/cexpr/tests/input/floats.h
third_party/rust/cexpr/tests/input/int_signed.h
third_party/rust/cexpr/tests/input/int_unsigned.h
third_party/rust/cexpr/tests/input/strings.h
third_party/rust/clang-sys/.cargo-checksum.json
third_party/rust/clang-sys/.cargo-ok
third_party/rust/clang-sys/.gitignore
third_party/rust/clang-sys/.travis.yml
third_party/rust/clang-sys/CHANGELOG.md
third_party/rust/clang-sys/CONTRIBUTING.md
third_party/rust/clang-sys/Cargo.toml
third_party/rust/clang-sys/LICENSE.txt
third_party/rust/clang-sys/README.md
third_party/rust/clang-sys/appveyor.yml
third_party/rust/clang-sys/build.rs
third_party/rust/clang-sys/ci/before_install.sh
third_party/rust/clang-sys/ci/install.bat
third_party/rust/clang-sys/ci/script.sh
third_party/rust/clang-sys/ci/test_script.bat
third_party/rust/clang-sys/clippy.toml
third_party/rust/clang-sys/src/lib.rs
third_party/rust/clang-sys/src/link.rs
third_party/rust/clang-sys/src/support.rs
third_party/rust/clang-sys/tests/header.h
third_party/rust/clang-sys/tests/lib.rs
third_party/rust/glob/.cargo-checksum.json
third_party/rust/glob/.cargo-ok
third_party/rust/glob/.gitignore
third_party/rust/glob/.travis.yml
third_party/rust/glob/Cargo.toml
third_party/rust/glob/LICENSE-APACHE
third_party/rust/glob/LICENSE-MIT
third_party/rust/glob/README.md
third_party/rust/glob/src/lib.rs
third_party/rust/glob/tests/glob-std.rs
third_party/rust/lazy_static-0.1.16/.cargo-checksum.json
third_party/rust/lazy_static-0.1.16/.cargo-ok
third_party/rust/lazy_static-0.1.16/.gitignore
third_party/rust/lazy_static-0.1.16/.travis.yml
third_party/rust/lazy_static-0.1.16/Cargo.toml
third_party/rust/lazy_static-0.1.16/LICENSE
third_party/rust/lazy_static-0.1.16/README.md
third_party/rust/lazy_static-0.1.16/src/lib.rs
third_party/rust/lazy_static-0.1.16/src/liblib.so
third_party/rust/lazy_static-0.1.16/tests/test.rs
third_party/rust/libbindgen/.cargo-checksum.json
third_party/rust/libbindgen/.cargo-ok
third_party/rust/libbindgen/Cargo.toml
third_party/rust/libbindgen/README.md
third_party/rust/libbindgen/build.rs
third_party/rust/libbindgen/src/chooser.rs
third_party/rust/libbindgen/src/clang.rs
third_party/rust/libbindgen/src/clangll.rs
third_party/rust/libbindgen/src/codegen/helpers.rs
third_party/rust/libbindgen/src/codegen/mod.rs
third_party/rust/libbindgen/src/ir/annotations.rs
third_party/rust/libbindgen/src/ir/comp.rs
third_party/rust/libbindgen/src/ir/context.rs
third_party/rust/libbindgen/src/ir/enum_ty.rs
third_party/rust/libbindgen/src/ir/function.rs
third_party/rust/libbindgen/src/ir/int.rs
third_party/rust/libbindgen/src/ir/item.rs
third_party/rust/libbindgen/src/ir/item_kind.rs
third_party/rust/libbindgen/src/ir/layout.rs
third_party/rust/libbindgen/src/ir/mod.rs
third_party/rust/libbindgen/src/ir/module.rs
third_party/rust/libbindgen/src/ir/ty.rs
third_party/rust/libbindgen/src/ir/type_collector.rs
third_party/rust/libbindgen/src/ir/var.rs
third_party/rust/libbindgen/src/lib.rs
third_party/rust/libbindgen/src/log_stubs.rs
third_party/rust/libbindgen/src/parse.rs
third_party/rust/libbindgen/src/regex_set.rs
third_party/rust/libbindgen/src/uses.rs
third_party/rust/libbindgen/tests/headers/accessors.hpp
third_party/rust/libbindgen/tests/headers/annotation_hide.hpp
third_party/rust/libbindgen/tests/headers/anon_enum.hpp
third_party/rust/libbindgen/tests/headers/anon_enum_whitelist.h
third_party/rust/libbindgen/tests/headers/anon_union.hpp
third_party/rust/libbindgen/tests/headers/arg_keyword.hpp
third_party/rust/libbindgen/tests/headers/base-to-derived.hpp
third_party/rust/libbindgen/tests/headers/bitfield-enum-basic.hpp
third_party/rust/libbindgen/tests/headers/bitfield_method_mangling.h
third_party/rust/libbindgen/tests/headers/blocks.h
third_party/rust/libbindgen/tests/headers/canonical_path_without_namespacing.hpp
third_party/rust/libbindgen/tests/headers/class.hpp
third_party/rust/libbindgen/tests/headers/class_nested.hpp
third_party/rust/libbindgen/tests/headers/class_no_members.hpp
third_party/rust/libbindgen/tests/headers/class_static.hpp
third_party/rust/libbindgen/tests/headers/class_static_const.hpp
third_party/rust/libbindgen/tests/headers/class_use_as.hpp
third_party/rust/libbindgen/tests/headers/class_with_dtor.hpp
third_party/rust/libbindgen/tests/headers/class_with_inner_struct.hpp
third_party/rust/libbindgen/tests/headers/class_with_typedef.hpp
third_party/rust/libbindgen/tests/headers/complex.h
third_party/rust/libbindgen/tests/headers/complex_global.h
third_party/rust/libbindgen/tests/headers/const_bool.hpp
third_party/rust/libbindgen/tests/headers/const_enum_unnamed.hpp
third_party/rust/libbindgen/tests/headers/const_ptr.hpp
third_party/rust/libbindgen/tests/headers/const_resolved_ty.h
third_party/rust/libbindgen/tests/headers/const_tparam.hpp
third_party/rust/libbindgen/tests/headers/constant-evaluate.h
third_party/rust/libbindgen/tests/headers/convert-floats.h
third_party/rust/libbindgen/tests/headers/crtp.hpp
third_party/rust/libbindgen/tests/headers/dash_language.h
third_party/rust/libbindgen/tests/headers/decl_extern_int_twice.h
third_party/rust/libbindgen/tests/headers/decl_ptr_to_array.h
third_party/rust/libbindgen/tests/headers/disable-namespacing.hpp
third_party/rust/libbindgen/tests/headers/duplicated-namespaces-definitions.hpp
third_party/rust/libbindgen/tests/headers/duplicated-namespaces.hpp
third_party/rust/libbindgen/tests/headers/duplicated_constants_in_ns.hpp
third_party/rust/libbindgen/tests/headers/elaborated.hpp
third_party/rust/libbindgen/tests/headers/empty_template_param_name.hpp
third_party/rust/libbindgen/tests/headers/enum.h
third_party/rust/libbindgen/tests/headers/enum_alias.hpp
third_party/rust/libbindgen/tests/headers/enum_and_vtable_mangling.hpp
third_party/rust/libbindgen/tests/headers/enum_dupe.h
third_party/rust/libbindgen/tests/headers/enum_explicit_type.hpp
third_party/rust/libbindgen/tests/headers/enum_negative.h
third_party/rust/libbindgen/tests/headers/enum_packed.h
third_party/rust/libbindgen/tests/headers/eval-variadic-template-parameter.hpp
third_party/rust/libbindgen/tests/headers/extern.hpp
third_party/rust/libbindgen/tests/headers/float128.hpp
third_party/rust/libbindgen/tests/headers/forward-inherit-struct-with-fields.hpp
third_party/rust/libbindgen/tests/headers/forward-inherit-struct.hpp
third_party/rust/libbindgen/tests/headers/forward_declared_struct.h
third_party/rust/libbindgen/tests/headers/func_proto.h
third_party/rust/libbindgen/tests/headers/func_ptr.h
third_party/rust/libbindgen/tests/headers/func_ptr_in_struct.h
third_party/rust/libbindgen/tests/headers/func_with_array_arg.h
third_party/rust/libbindgen/tests/headers/func_with_func_ptr_arg.h
third_party/rust/libbindgen/tests/headers/in_class_typedef.hpp
third_party/rust/libbindgen/tests/headers/inherit-namespaced.hpp
third_party/rust/libbindgen/tests/headers/inherit_named.hpp
third_party/rust/libbindgen/tests/headers/inherit_typedef.hpp
third_party/rust/libbindgen/tests/headers/inner_const.hpp
third_party/rust/libbindgen/tests/headers/inner_template_self.hpp
third_party/rust/libbindgen/tests/headers/int128_t.h
third_party/rust/libbindgen/tests/headers/issue_311.hpp
third_party/rust/libbindgen/tests/headers/issue_315.hpp
third_party/rust/libbindgen/tests/headers/jsval_layout_opaque.hpp
third_party/rust/libbindgen/tests/headers/keywords.h
third_party/rust/libbindgen/tests/headers/macro-expr-basic.h
third_party/rust/libbindgen/tests/headers/macro-redef.h
third_party/rust/libbindgen/tests/headers/macro_const.h
third_party/rust/libbindgen/tests/headers/maddness-is-avoidable.hpp
third_party/rust/libbindgen/tests/headers/module-whitelisted.hpp
third_party/rust/libbindgen/tests/headers/msvc-no-usr.hpp
third_party/rust/libbindgen/tests/headers/multiple-inherit-empty-correct-layout.hpp
third_party/rust/libbindgen/tests/headers/mutable.hpp
third_party/rust/libbindgen/tests/headers/namespace.hpp
third_party/rust/libbindgen/tests/headers/nested.hpp
third_party/rust/libbindgen/tests/headers/nested_vtable.hpp
third_party/rust/libbindgen/tests/headers/nested_within_namespace.hpp
third_party/rust/libbindgen/tests/headers/no-std.h
third_party/rust/libbindgen/tests/headers/no_copy.hpp
third_party/rust/libbindgen/tests/headers/nsStyleAutoArray.hpp
third_party/rust/libbindgen/tests/headers/only_bitfields.hpp
third_party/rust/libbindgen/tests/headers/opaque_in_struct.hpp
third_party/rust/libbindgen/tests/headers/opaque_pointer.hpp
third_party/rust/libbindgen/tests/headers/opaque_typedef.hpp
third_party/rust/libbindgen/tests/headers/overflowed_enum.hpp
third_party/rust/libbindgen/tests/headers/overloading.hpp
third_party/rust/libbindgen/tests/headers/private.hpp
third_party/rust/libbindgen/tests/headers/redeclaration.hpp
third_party/rust/libbindgen/tests/headers/ref_argument_array.hpp
third_party/rust/libbindgen/tests/headers/reparented_replacement.hpp
third_party/rust/libbindgen/tests/headers/replace_template_alias.hpp
third_party/rust/libbindgen/tests/headers/replace_use.hpp
third_party/rust/libbindgen/tests/headers/replaces_double.hpp
third_party/rust/libbindgen/tests/headers/same_struct_name_in_different_namespaces.hpp
third_party/rust/libbindgen/tests/headers/size_t_template.hpp
third_party/rust/libbindgen/tests/headers/struct_containing_forward_declared_struct.h
third_party/rust/libbindgen/tests/headers/struct_with_anon_struct.h
third_party/rust/libbindgen/tests/headers/struct_with_anon_struct_array.h
third_party/rust/libbindgen/tests/headers/struct_with_anon_struct_pointer.h
third_party/rust/libbindgen/tests/headers/struct_with_anon_union.h
third_party/rust/libbindgen/tests/headers/struct_with_anon_unnamed_struct.h
third_party/rust/libbindgen/tests/headers/struct_with_anon_unnamed_union.h
third_party/rust/libbindgen/tests/headers/struct_with_bitfields.h
third_party/rust/libbindgen/tests/headers/struct_with_derive_debug.h
third_party/rust/libbindgen/tests/headers/struct_with_nesting.h
third_party/rust/libbindgen/tests/headers/struct_with_packing.h
third_party/rust/libbindgen/tests/headers/struct_with_struct.h
third_party/rust/libbindgen/tests/headers/struct_with_typedef_template_arg.hpp
third_party/rust/libbindgen/tests/headers/template.hpp
third_party/rust/libbindgen/tests/headers/template_alias.hpp
third_party/rust/libbindgen/tests/headers/template_alias_basic.hpp
third_party/rust/libbindgen/tests/headers/template_alias_namespace.hpp
third_party/rust/libbindgen/tests/headers/template_typedef_transitive_param.hpp
third_party/rust/libbindgen/tests/headers/template_typedefs.hpp
third_party/rust/libbindgen/tests/headers/templateref_opaque.hpp
third_party/rust/libbindgen/tests/headers/type-referenced-by-whitelisted-function.h
third_party/rust/libbindgen/tests/headers/type_alias_empty.hpp
third_party/rust/libbindgen/tests/headers/type_alias_partial_template_especialization.hpp
third_party/rust/libbindgen/tests/headers/type_alias_template_specialized.hpp
third_party/rust/libbindgen/tests/headers/typeref.hpp
third_party/rust/libbindgen/tests/headers/union-in-ns.hpp
third_party/rust/libbindgen/tests/headers/union_dtor.hpp
third_party/rust/libbindgen/tests/headers/union_fields.hpp
third_party/rust/libbindgen/tests/headers/union_template.hpp
third_party/rust/libbindgen/tests/headers/union_with_anon_struct.h
third_party/rust/libbindgen/tests/headers/union_with_anon_struct_bitfield.h
third_party/rust/libbindgen/tests/headers/union_with_anon_union.h
third_party/rust/libbindgen/tests/headers/union_with_anon_unnamed_struct.h
third_party/rust/libbindgen/tests/headers/union_with_anon_unnamed_union.h
third_party/rust/libbindgen/tests/headers/union_with_big_member.h
third_party/rust/libbindgen/tests/headers/union_with_nesting.h
third_party/rust/libbindgen/tests/headers/unknown_attr.h
third_party/rust/libbindgen/tests/headers/use-core.h
third_party/rust/libbindgen/tests/headers/using.hpp
third_party/rust/libbindgen/tests/headers/variadic_template_function.hpp
third_party/rust/libbindgen/tests/headers/vector.hpp
third_party/rust/libbindgen/tests/headers/virtual_dtor.hpp
third_party/rust/libbindgen/tests/headers/virtual_overloaded.hpp
third_party/rust/libbindgen/tests/headers/vtable_recursive_sig.hpp
third_party/rust/libbindgen/tests/headers/weird_bitfields.hpp
third_party/rust/libbindgen/tests/headers/what_is_going_on.hpp
third_party/rust/libbindgen/tests/headers/whitelist-namespaces-basic.hpp
third_party/rust/libbindgen/tests/headers/whitelist-namespaces.hpp
third_party/rust/libbindgen/tests/headers/whitelist_basic.hpp
third_party/rust/libbindgen/tests/headers/whitelist_fix.hpp
third_party/rust/libbindgen/tests/headers/whitelist_vars.h
third_party/rust/libbindgen/tests/tests.rs
third_party/rust/libbindgen/tests/uses/.gitignore
third_party/rust/nom/.cargo-checksum.json
third_party/rust/nom/.cargo-ok
third_party/rust/nom/.gitignore
third_party/rust/nom/.travis.yml
third_party/rust/nom/CHANGELOG.md
third_party/rust/nom/Cargo.toml
third_party/rust/nom/LICENSE
third_party/rust/nom/src/bits.rs
third_party/rust/nom/src/bytes.rs
third_party/rust/nom/src/character.rs
third_party/rust/nom/src/internal.rs
third_party/rust/nom/src/lib.rs
third_party/rust/nom/src/macros.rs
third_party/rust/nom/src/methods.rs
third_party/rust/nom/src/nom.rs
third_party/rust/nom/src/regexp.rs
third_party/rust/nom/src/str.rs
third_party/rust/nom/src/stream.rs
third_party/rust/nom/src/util.rs
third_party/rust/nom/tests/arithmetic.rs
third_party/rust/nom/tests/arithmetic_ast.rs
third_party/rust/nom/tests/cross_function_backtracking.rs
third_party/rust/nom/tests/ini.rs
third_party/rust/nom/tests/ini_str.rs
third_party/rust/nom/tests/issues.rs
third_party/rust/nom/tests/mp4.rs
third_party/rust/nom/tests/omnom.rs
third_party/rust/nom/tests/test1.rs
third_party/rust/quasi/.cargo-checksum.json
third_party/rust/quasi/.cargo-ok
third_party/rust/quasi/Cargo.toml
third_party/rust/quasi/src/lib.rs
third_party/rust/quasi_codegen/.cargo-checksum.json
third_party/rust/quasi_codegen/.cargo-ok
third_party/rust/quasi_codegen/Cargo.toml
third_party/rust/quasi_codegen/src/lib.rs
third_party/rust/syntex/.cargo-checksum.json
third_party/rust/syntex/.cargo-ok
third_party/rust/syntex/Cargo.toml
third_party/rust/syntex/src/error.rs
third_party/rust/syntex/src/lib.rs
third_party/rust/syntex/src/registry.rs
third_party/rust/syntex/src/resolver.rs
third_party/rust/syntex/src/stack.rs
third_party/rust/syntex_errors/.cargo-checksum.json
third_party/rust/syntex_errors/.cargo-ok
third_party/rust/syntex_errors/Cargo.toml
third_party/rust/syntex_errors/src/diagnostic.rs
third_party/rust/syntex_errors/src/diagnostic_builder.rs
third_party/rust/syntex_errors/src/emitter.rs
third_party/rust/syntex_errors/src/lib.rs
third_party/rust/syntex_errors/src/lock.rs
third_party/rust/syntex_errors/src/registry.rs
third_party/rust/syntex_errors/src/snippet.rs
third_party/rust/syntex_errors/src/styled_buffer.rs
third_party/rust/syntex_pos/.cargo-checksum.json
third_party/rust/syntex_pos/.cargo-ok
third_party/rust/syntex_pos/Cargo.toml
third_party/rust/syntex_pos/src/lib.rs
third_party/rust/syntex_syntax/.cargo-checksum.json
third_party/rust/syntex_syntax/.cargo-ok
third_party/rust/syntex_syntax/Cargo.toml
third_party/rust/syntex_syntax/src/abi.rs
third_party/rust/syntex_syntax/src/ast.rs
third_party/rust/syntex_syntax/src/attr.rs
third_party/rust/syntex_syntax/src/codemap.rs
third_party/rust/syntex_syntax/src/config.rs
third_party/rust/syntex_syntax/src/diagnostic_list.rs
third_party/rust/syntex_syntax/src/diagnostics/macros.rs
third_party/rust/syntex_syntax/src/diagnostics/metadata.rs
third_party/rust/syntex_syntax/src/diagnostics/plugin.rs
third_party/rust/syntex_syntax/src/entry.rs
third_party/rust/syntex_syntax/src/ext/base.rs
third_party/rust/syntex_syntax/src/ext/build.rs
third_party/rust/syntex_syntax/src/ext/decorator.rs
third_party/rust/syntex_syntax/src/ext/env.rs
third_party/rust/syntex_syntax/src/ext/expand.rs
third_party/rust/syntex_syntax/src/ext/hygiene.rs
third_party/rust/syntex_syntax/src/ext/placeholders.rs
third_party/rust/syntex_syntax/src/ext/proc_macro_shim.rs
third_party/rust/syntex_syntax/src/ext/quote.rs
third_party/rust/syntex_syntax/src/ext/source_util.rs
third_party/rust/syntex_syntax/src/ext/tt/macro_parser.rs
third_party/rust/syntex_syntax/src/ext/tt/macro_rules.rs
third_party/rust/syntex_syntax/src/ext/tt/transcribe.rs
third_party/rust/syntex_syntax/src/feature_gate.rs
third_party/rust/syntex_syntax/src/fold.rs
third_party/rust/syntex_syntax/src/json.rs
third_party/rust/syntex_syntax/src/lib.rs
third_party/rust/syntex_syntax/src/parse/attr.rs
third_party/rust/syntex_syntax/src/parse/classify.rs
third_party/rust/syntex_syntax/src/parse/common.rs
third_party/rust/syntex_syntax/src/parse/lexer/comments.rs
third_party/rust/syntex_syntax/src/parse/lexer/mod.rs
third_party/rust/syntex_syntax/src/parse/lexer/unicode_chars.rs
third_party/rust/syntex_syntax/src/parse/mod.rs
third_party/rust/syntex_syntax/src/parse/obsolete.rs
third_party/rust/syntex_syntax/src/parse/parser.rs
third_party/rust/syntex_syntax/src/parse/token.rs
third_party/rust/syntex_syntax/src/print/pp.rs
third_party/rust/syntex_syntax/src/print/pprust.rs
third_party/rust/syntex_syntax/src/ptr.rs
third_party/rust/syntex_syntax/src/show_span.rs
third_party/rust/syntex_syntax/src/std_inject.rs
third_party/rust/syntex_syntax/src/str.rs
third_party/rust/syntex_syntax/src/test.rs
third_party/rust/syntex_syntax/src/tokenstream.rs
third_party/rust/syntex_syntax/src/util/interner.rs
third_party/rust/syntex_syntax/src/util/lev_distance.rs
third_party/rust/syntex_syntax/src/util/move_map.rs
third_party/rust/syntex_syntax/src/util/node_count.rs
third_party/rust/syntex_syntax/src/util/parser.rs
third_party/rust/syntex_syntax/src/util/parser_testing.rs
third_party/rust/syntex_syntax/src/util/small_vector.rs
third_party/rust/syntex_syntax/src/util/thin_vec.rs
third_party/rust/syntex_syntax/src/visit.rs
third_party/rust/term/.cargo-checksum.json
third_party/rust/term/.cargo-ok
third_party/rust/term/.gitignore
third_party/rust/term/.travis.yml
third_party/rust/term/Cargo.toml
third_party/rust/term/LICENSE-APACHE
third_party/rust/term/LICENSE-MIT
third_party/rust/term/README.md
third_party/rust/term/appveyor.yml
third_party/rust/term/rustfmt.toml
third_party/rust/term/scripts/id_rsa.enc
third_party/rust/term/scripts/travis-doc-upload.cfg
third_party/rust/term/src/lib.rs
third_party/rust/term/src/terminfo/mod.rs
third_party/rust/term/src/terminfo/parm.rs
third_party/rust/term/src/terminfo/parser/compiled.rs
third_party/rust/term/src/terminfo/parser/names.rs
third_party/rust/term/src/terminfo/searcher.rs
third_party/rust/term/src/win.rs
third_party/rust/term/tests/data/dumb
third_party/rust/term/tests/data/linux
third_party/rust/term/tests/data/linux-16color
third_party/rust/term/tests/data/linux-basic
third_party/rust/term/tests/data/linux-c
third_party/rust/term/tests/data/linux-c-nc
third_party/rust/term/tests/data/linux-koi8
third_party/rust/term/tests/data/linux-koi8r
third_party/rust/term/tests/data/linux-lat
third_party/rust/term/tests/data/linux-m
third_party/rust/term/tests/data/linux-nic
third_party/rust/term/tests/data/linux-vt
third_party/rust/term/tests/data/linux2.2
third_party/rust/term/tests/data/linux2.6
third_party/rust/term/tests/data/linux2.6.26
third_party/rust/term/tests/data/linux3.0
third_party/rust/term/tests/data/rxvt
third_party/rust/term/tests/data/rxvt-16color
third_party/rust/term/tests/data/rxvt-256color
third_party/rust/term/tests/data/rxvt-88color
third_party/rust/term/tests/data/rxvt-basic
third_party/rust/term/tests/data/rxvt-color
third_party/rust/term/tests/data/rxvt-cygwin
third_party/rust/term/tests/data/rxvt-cygwin-native
third_party/rust/term/tests/data/rxvt-xpm
third_party/rust/term/tests/data/screen
third_party/rust/term/tests/data/screen-256color
third_party/rust/term/tests/data/xterm
third_party/rust/term/tests/data/xterm-256color
third_party/rust/term/tests/terminfo.rs
third_party/rust/unicode-xid/.cargo-checksum.json
third_party/rust/unicode-xid/.cargo-ok
third_party/rust/unicode-xid/.gitignore
third_party/rust/unicode-xid/.travis.yml
third_party/rust/unicode-xid/COPYRIGHT
third_party/rust/unicode-xid/Cargo.toml
third_party/rust/unicode-xid/LICENSE-APACHE
third_party/rust/unicode-xid/LICENSE-MIT
third_party/rust/unicode-xid/README.md
third_party/rust/unicode-xid/scripts/unicode.py
third_party/rust/unicode-xid/src/lib.rs
third_party/rust/unicode-xid/src/tables.rs
third_party/rust/unicode-xid/src/tests.rs
toolkit/library/gtest/rust/Cargo.lock
toolkit/library/rust/Cargo.lock
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"9dbd7d392dd88808cd252ab186b368db6e37ca75a34757ba94b12e48467e6075","src/arm.rs":"83b6ba22ded921ae45e02888e879b2ae73d4659db53e6552675433c3c2e0ed21","src/attr.rs":"d1eff83ec39e77033c3d8fde744405faf65756744d53518765b83a5813424478","src/block.rs":"71e2268ba151b7ee60a2fe0b0b3a7cf3e2ce3bff4fb0ee260db70ad9b1cd8826","src/constant.rs":"471b0ffc52684733a598a43e08b1719bf6852c26eca74e7f5105f0f964543980","src/ctx.rs":"738213a64a96cfe3beba6d08d82d89d48dc384b37fe726621b324bac5c017859","src/expr.rs":"db6613923e5fd016f69ea6283a9c99ddc10a73183c8a5acedb983f224720c9ab","src/fn_decl.rs":"85c30d78942bb7cda0c6bddcf55f1a35b3581a99fb15e33f3abf2763b84f8073","src/generics.rs":"5bce5cb6f7331eb75ecf8cd236b0f0ae19838a014ee931de25605a783234a125","src/ident.rs":"d4fd728f2f3c6fe85bce20f573496ef64696cfa46343009f394b32868e308c78","src/invoke.rs":"03f52dd0b135e8ffcc52c3802cdf8d516ef4a53e393ce4bdd82ced19fd106b88","src/item.rs":"c6857ba95397a6db3cd8bb5a88794eeeb8920ee5a1cce8a7d47d34c681cf32f9","src/lib.rs":"92f93d3aa081b7107c6132cbcf7bfa20a0e21f6456f54accd7561a7a246d7c39","src/lifetime.rs":"348ecc239aafa45128c7e214635b6cc597e093c33a22c204c0c55a48b3a0b5a1","src/lit.rs":"b7c0c677fef8b86f8178a722a004efa066b11bf268642137307689d2bec9b405","src/mac.rs":"98d6fadb0c774a55410fe51559b984e7831934198b6fc5e80ba371e94de562a1","src/method.rs":"bce543c148022170decd0cff9af3b37781323bcdf0dc35e23beec5f200dbc549","src/name.rs":"1444a9e79dca2ada73519e64c6a46050153ae5f02e5c8ce5ad6a5581f8be641a","src/pat.rs":"0c3c0cb22054d09a2b7df277e4c05023c079d655d54b66a6bf732d56d58971e0","src/path.rs":"dfeeae8d90e4f670b5a66f1c15dbfc8f2ea1cd0b9bda5eebe876f7163b860c58","src/qpath.rs":"bb00b9d63d6be1caf40a3eb0395834ec1025543060fcc0e7955835e231b6e6f8","src/self_.rs":"565780ba85ba851675331cd60dbe8a43f5eb87c318f6cc3b11bb7ba77a0d53fa","src/stmt.rs":"99e577b1417ff66c3057454ca27266a19329c6896b0f36259dcbdba0ff0005fb","src/str.rs":"c3efbf7b15cb2333f683e357db62d22311e833ee4330347eb23c66c5a0603ecf","src/struct_field.rs":"189fa910e236fea815d85c6b4535a76e6e7151a9d113a806bb60c6a192c7042b","src/ty.rs":"c569ff2833e939bc8537310cf13b4eedebe2e0a3e63ea62e232f7856a00fb988","src/ty_param.rs":"ae253dfaf964ac5e9bbb6d5aedb631bb491c5e602c9cf9038c886dd2707e48e6","src/variant.rs":"7fed49d694e029c81b4b70095e00704f1c67ef6357d122157d305f85dd95a512","src/variant_data.rs":"346198e982a2549ed4942ac7c6581f222f6284392afd9c0898acbfa53f58ffd3","src/where_predicate.rs":"f8bb7d2ea112986196f62c3deae58afe7e78d6b1c5bc622aeb3ecd51d77e7e10"},"package":"88bb8ecdf6a7eaddb7bfd872ebf5e085d343ca42ce98c582dba8046e3450b524"}
\ No newline at end of file
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+name = "aster"
+version = "0.34.0"
+authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
+license = "MIT/Apache-2.0"
+description = "A libsyntax ast builder"
+repository = "https://github.com/serde-rs/aster"
+include = ["Cargo.toml", "src/**/*.rs"]
+
+[features]
+with-syntex = ["syntex_syntax"]
+unstable-testing = ["clippy", "compiletest_rs"]
+
+[dependencies]
+syntex_syntax = { version = "^0.50.0", optional = true }
+clippy = { version = "0.*", optional = true }
+compiletest_rs = { version = "^0.2.0", optional = true }
+
+[[test]]
+name = "test"
+path = "tests/test.rs"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/arm.rs
@@ -0,0 +1,241 @@
+#![cfg_attr(feature = "unstable", allow(should_implement_trait))]
+
+use std::iter::IntoIterator;
+
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span};
+use syntax::ptr::P;
+
+use attr::AttrBuilder;
+use expr::ExprBuilder;
+use invoke::{Invoke, Identity};
+use pat::PatBuilder;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ArmBuilder<F=Identity> {
+    callback: F,
+    span: Span,
+    attrs: Vec<ast::Attribute>,
+}
+
+impl ArmBuilder {
+    pub fn new() -> Self {
+        ArmBuilder::with_callback(Identity)
+    }
+}
+
+impl<F> ArmBuilder<F>
+    where F: Invoke<ast::Arm>,
+{
+    pub fn with_callback(callback: F) -> Self {
+        ArmBuilder {
+            callback: callback,
+            span: DUMMY_SP,
+            attrs: Vec::new(),
+        }
+    }
+
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn with_attrs<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=ast::Attribute>,
+    {
+        self.attrs.extend(iter);
+        self
+    }
+
+    pub fn with_attr(mut self, attr: ast::Attribute) -> Self {
+        self.attrs.push(attr);
+        self
+    }
+
+    pub fn attr(self) -> AttrBuilder<Self> {
+        AttrBuilder::with_callback(self)
+    }
+
+    pub fn with_pats<I>(self, iter: I) -> ArmPatBuilder<F>
+        where I: IntoIterator<Item=P<ast::Pat>>,
+    {
+        ArmPatBuilder {
+            callback: self.callback,
+            span: self.span,
+            attrs: self.attrs,
+            pats: iter.into_iter().collect(),
+        }
+    }
+
+    pub fn with_pat(self, pat: P<ast::Pat>) -> ArmPatBuilder<F> {
+        ArmPatBuilder {
+            callback: self.callback,
+            span: self.span,
+            attrs: self.attrs,
+            pats: vec![pat],
+        }
+    }
+
+    pub fn pat(self) -> PatBuilder<Self> {
+        PatBuilder::with_callback(self)
+    }
+
+    /*
+    pub fn with_guard(self, guard: Option<P<ast::Expr>>) -> ExprBuilder<ArmBodyBuilder<F>> {
+        ExprBuilder::with_callback(ArmBodyBuilder {
+            builder: self,
+            guard: guard,
+        })
+    }
+
+    pub fn guard(self) -> ExprBuilder<Self> {
+        ExprBuilder::with_callback(self)
+    }
+
+    pub fn body(self) -> ExprBuilder<ArmBodyBuilder<F>> {
+        self.with_guard(None)
+    }
+
+    pub fn build_arm_(self,
+                      guard: Option<P<ast::Expr>>,
+                      body: P<ast::Expr>) -> F::Result {
+        self.callback.invoke(ast::Arm {
+            attrs: self.attrs,
+            pats: self.pats,
+            guard: guard,
+            body: body,
+        })
+    }
+    */
+}
+
+impl<F> Invoke<ast::Attribute> for ArmBuilder<F>
+    where F: Invoke<ast::Arm>,
+{
+    type Result = Self;
+
+    fn invoke(self, attr: ast::Attribute) -> Self {
+        self.with_attr(attr)
+    }
+}
+
+impl<F> Invoke<P<ast::Pat>> for ArmBuilder<F>
+    where F: Invoke<ast::Arm>,
+{
+    type Result = ArmPatBuilder<F>;
+
+    fn invoke(self, pat: P<ast::Pat>) -> ArmPatBuilder<F> {
+        self.with_pat(pat)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ArmPatBuilder<F> {
+    callback: F,
+    span: Span,
+    attrs: Vec<ast::Attribute>,
+    pats: Vec<P<ast::Pat>>,
+}
+
+impl<F> ArmPatBuilder<F>
+    where F: Invoke<ast::Arm>,
+{
+    pub fn with_pats<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=P<ast::Pat>>,
+    {
+        self.pats.extend(iter);
+        self
+    }
+
+    pub fn with_pat(mut self, pat: P<ast::Pat>) -> Self {
+        self.pats.push(pat);
+        self
+    }
+
+    pub fn pat(self) -> PatBuilder<Self> {
+        let span = self.span;
+        PatBuilder::with_callback(self).span(span)
+    }
+
+    pub fn with_guard(self, guard: Option<P<ast::Expr>>) -> ArmBodyBuilder<F> {
+        ArmBodyBuilder {
+            builder: self,
+            guard: guard,
+        }
+    }
+
+    pub fn guard(self) -> ExprBuilder<Self> {
+        let span = self.span;
+        ExprBuilder::with_callback(self).span(span)
+    }
+
+    pub fn body(self) -> ExprBuilder<ArmBodyBuilder<F>> {
+        ArmBodyBuilder {
+            builder: self,
+            guard: None,
+        }.body()
+    }
+
+    pub fn build_arm_(self,
+                      guard: Option<P<ast::Expr>>,
+                      body: P<ast::Expr>) -> F::Result {
+        self.callback.invoke(ast::Arm {
+            attrs: self.attrs,
+            pats: self.pats,
+            guard: guard,
+            body: body,
+        })
+    }
+}
+
+impl<F> Invoke<P<ast::Pat>> for ArmPatBuilder<F>
+    where F: Invoke<ast::Arm>,
+{
+    type Result = Self;
+
+    fn invoke(self, pat: P<ast::Pat>) -> Self {
+        self.with_pat(pat)
+    }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ArmPatBuilder<F>
+    where F: Invoke<ast::Arm>,
+{
+    type Result = ArmBodyBuilder<F>;
+
+    fn invoke(self, guard: P<ast::Expr>) -> ArmBodyBuilder<F> {
+        self.with_guard(Some(guard))
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ArmBodyBuilder<F> {
+    builder: ArmPatBuilder<F>,
+    guard: Option<P<ast::Expr>>,
+}
+
+impl<F> ArmBodyBuilder<F>
+    where F: Invoke<ast::Arm>,
+{
+    pub fn body(self) -> ExprBuilder<ArmBodyBuilder<F>> {
+        let span = self.builder.span;
+        ExprBuilder::with_callback(self).span(span)
+    }
+
+    pub fn build(self, body: P<ast::Expr>) -> F::Result {
+        self.builder.build_arm_(self.guard, body)
+    }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ArmBodyBuilder<F>
+    where F: Invoke<ast::Arm>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, body: P<ast::Expr>) -> F::Result {
+        self.build(body)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/attr.rs
@@ -0,0 +1,291 @@
+use std::iter::IntoIterator;
+
+use syntax::ast;
+use syntax::attr;
+use syntax::codemap::{DUMMY_SP, Span, respan};
+use syntax::parse::token;
+use syntax::ptr::P;
+
+use invoke::{Invoke, Identity};
+use lit::LitBuilder;
+use str::ToInternedString;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct AttrBuilder<F=Identity> {
+    callback: F,
+    span: Span,
+    style: ast::AttrStyle,
+    is_sugared_doc: bool,
+}
+
+impl AttrBuilder {
+    pub fn new() -> Self {
+        AttrBuilder::with_callback(Identity)
+    }
+}
+
+impl<F> AttrBuilder<F>
+    where F: Invoke<ast::Attribute>,
+{
+    pub fn with_callback(callback: F) -> Self {
+        AttrBuilder {
+            callback: callback,
+            span: DUMMY_SP,
+            style: ast::AttrStyle::Outer,
+            is_sugared_doc: false,
+        }
+    }
+
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn inner(mut self) -> Self {
+        self.style = ast::AttrStyle::Inner;
+        self
+    }
+
+    pub fn build_meta_item(self, item: P<ast::MetaItem>) -> F::Result {
+        let attr = respan(self.span, ast::Attribute_ {
+            id: attr::mk_attr_id(),
+            style: self.style,
+            value: item,
+            is_sugared_doc: self.is_sugared_doc,
+        });
+        self.callback.invoke(attr)
+    }
+
+    pub fn build_meta_item_(self, item: ast::MetaItemKind) -> F::Result {
+        let item = P(respan(self.span, item));
+        self.build_meta_item(item)
+    }
+
+    pub fn word<T>(self, word: T) -> F::Result
+        where T: ToInternedString
+    {
+        self.build_meta_item_(ast::MetaItemKind::Word(word.to_interned_string()))
+    }
+
+    pub fn list<T>(self, word: T) -> AttrListBuilder<Self>
+        where T: ToInternedString
+    {
+        AttrListBuilder::with_callback(word, self)
+    }
+
+    pub fn name_value<T>(self, name: T) -> LitBuilder<AttrNameValueBuilder<Self>>
+        where T: ToInternedString,
+    {
+        LitBuilder::with_callback(AttrNameValueBuilder {
+            callback: self,
+            name: name.to_interned_string(),
+        })
+    }
+
+    pub fn automatically_derived(self) -> F::Result {
+        self.word("automatically_derived")
+    }
+
+    pub fn inline(self) -> F::Result {
+        self.word("inline")
+    }
+
+    pub fn test(self) -> F::Result {
+        self.word("test")
+    }
+
+    pub fn allow<I, T>(self, iter: I) -> F::Result
+        where I: IntoIterator<Item=T>,
+              T: ToInternedString,
+    {
+        self.list("allow").words(iter).build()
+    }
+
+    pub fn warn<I, T>(self, iter: I) -> F::Result
+        where I: IntoIterator<Item=T>,
+              T: ToInternedString,
+    {
+        self.list("warn").words(iter).build()
+    }
+
+    pub fn deny<I, T>(self, iter: I) -> F::Result
+        where I: IntoIterator<Item=T>,
+              T: ToInternedString,
+    {
+        self.list("deny").words(iter).build()
+    }
+
+    pub fn features<I, T>(self, iter: I) -> F::Result
+        where I: IntoIterator<Item=T>,
+              T: ToInternedString,
+    {
+        self.list("feature").words(iter).build()
+    }
+
+    pub fn plugins<I, T>(self, iter: I) -> F::Result
+        where I: IntoIterator<Item=T>,
+              T: ToInternedString,
+    {
+        self.list("plugin").words(iter).build()
+    }
+
+    /**
+     * Create a #[doc = "..."] node. Note that callers of this must make sure to prefix their
+     * comments with either "///" or "/\*\*" if an outer comment, or "//!" or "/\*!" if an inner
+     * comment.
+     */
+    pub fn doc<T>(mut self, doc: T) -> F::Result
+        where T: ToInternedString,
+    {
+        self.is_sugared_doc = true;
+        self.name_value("doc").str(doc)
+    }
+}
+
+impl<F> Invoke<P<ast::MetaItem>> for AttrBuilder<F>
+    where F: Invoke<ast::Attribute>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, item: P<ast::MetaItem>) -> F::Result {
+        self.build_meta_item(item)
+    }
+}
+
+impl<F> Invoke<ast::MetaItemKind> for AttrBuilder<F>
+    where F: Invoke<ast::Attribute>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, item: ast::MetaItemKind) -> F::Result {
+        self.build_meta_item_(item)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct AttrListBuilder<F> {
+    callback: F,
+    span: Span,
+    name: token::InternedString,
+    items: Vec<ast::NestedMetaItem>,
+}
+
+impl<F> AttrListBuilder<F>
+    where F: Invoke<P<ast::MetaItem>>,
+{
+    pub fn with_callback<T>(name: T, callback: F) -> Self
+        where T: ToInternedString,
+    {
+        AttrListBuilder {
+            callback: callback,
+            span: DUMMY_SP,
+            name: name.to_interned_string(),
+            items: vec![],
+        }
+    }
+
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn with_meta_items<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=P<ast::MetaItem>>,
+    {
+        let span = self.span;
+        self.items.extend(iter.into_iter().map(|meta_item| {
+            respan(span, ast::NestedMetaItemKind::MetaItem(meta_item))
+        }));
+        self
+    }
+
+    pub fn with_meta_items_<I>(self, iter: I) -> Self
+        where I: IntoIterator<Item=ast::MetaItemKind>,
+    {
+        let iter = iter.into_iter();
+        let span = self.span;
+        self.with_meta_items(iter.map(|item| P(respan(span, item))))
+    }
+
+    pub fn with_meta_item(mut self, item: P<ast::MetaItem>) -> Self {
+        self.items.push(respan(self.span, ast::NestedMetaItemKind::MetaItem(item)));
+        self
+    }
+
+    pub fn with_meta_item_kind(self, item: ast::MetaItemKind) -> Self {
+        let span = self.span;
+        self.with_meta_item(P(respan(span, item)))
+    }
+
+    pub fn words<I, T>(self, iter: I) -> Self
+        where I: IntoIterator<Item=T>,
+              T: ToInternedString,
+    {
+        let iter = iter.into_iter();
+        self.with_meta_items_(iter.map(|word| ast::MetaItemKind::Word(word.to_interned_string())))
+    }
+
+    pub fn word<T>(self, word: T) -> Self
+        where T: ToInternedString,
+    {
+        self.with_meta_item_kind(ast::MetaItemKind::Word(word.to_interned_string()))
+    }
+
+    pub fn list<T>(self, name: T) -> AttrListBuilder<Self>
+        where T: ToInternedString,
+    {
+        AttrListBuilder::with_callback(name, self)
+    }
+
+    pub fn name_value<T>(self, name: T) -> LitBuilder<AttrNameValueBuilder<Self>>
+        where T: ToInternedString,
+    {
+        LitBuilder::with_callback(AttrNameValueBuilder {
+            callback: self,
+            name: name.to_interned_string(),
+        })
+    }
+
+    pub fn build(self) -> F::Result {
+        let item = respan(self.span, ast::MetaItemKind::List(self.name, self.items));
+        self.callback.invoke(P(item))
+    }
+}
+
+impl<F> Invoke<P<ast::MetaItem>> for AttrListBuilder<F>
+    where F: Invoke<P<ast::MetaItem>>,
+{
+    type Result = Self;
+
+    fn invoke(self, item: P<ast::MetaItem>) -> Self {
+        self.with_meta_item(item)
+    }
+}
+
+impl<F> Invoke<ast::MetaItemKind> for AttrListBuilder<F>
+    where F: Invoke<P<ast::MetaItem>>,
+{
+    type Result = Self;
+
+    fn invoke(self, item: ast::MetaItemKind) -> Self {
+        self.with_meta_item_kind(item)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct AttrNameValueBuilder<F> {
+    callback: F,
+    name: token::InternedString,
+}
+
+impl<F: Invoke<ast::MetaItemKind>> Invoke<P<ast::Lit>> for AttrNameValueBuilder<F> {
+    type Result = F::Result;
+
+    fn invoke(self, value: P<ast::Lit>) -> F::Result {
+        let item = ast::MetaItemKind::NameValue(self.name, (*value).clone());
+        self.callback.invoke(item)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/block.rs
@@ -0,0 +1,110 @@
+use std::iter::IntoIterator;
+
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span};
+use syntax::ptr::P;
+
+use expr::ExprBuilder;
+use invoke::{Invoke, Identity};
+use stmt::StmtBuilder;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct BlockBuilder<F=Identity> {
+    callback: F,
+    span: Span,
+    stmts: Vec<ast::Stmt>,
+    block_check_mode: ast::BlockCheckMode,
+}
+
+impl BlockBuilder {
+    pub fn new() -> Self {
+        BlockBuilder::with_callback(Identity)
+    }
+}
+
+impl<F> BlockBuilder<F>
+    where F: Invoke<P<ast::Block>>,
+{
+    pub fn with_callback(callback: F) -> Self {
+        BlockBuilder {
+            callback: callback,
+            span: DUMMY_SP,
+            stmts: Vec::new(),
+            block_check_mode: ast::BlockCheckMode::Default,
+        }
+    }
+
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn unsafe_(mut self) -> Self {
+        let source = ast::UnsafeSource::CompilerGenerated;
+        self.block_check_mode = ast::BlockCheckMode::Unsafe(source);
+        self
+    }
+
+    pub fn with_stmts<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=ast::Stmt>
+    {
+        self.stmts.extend(iter);
+        self
+    }
+
+    pub fn with_stmt(mut self, stmt: ast::Stmt) -> Self {
+        self.stmts.push(stmt);
+        self
+    }
+
+    pub fn stmt(self) -> StmtBuilder<Self> {
+        let span = self.span;
+        StmtBuilder::with_callback(self).span(span)
+    }
+
+    pub fn build_expr(self, expr: P<ast::Expr>) -> F::Result {
+        self.build_(Some(expr))
+    }
+
+    pub fn expr(self) -> ExprBuilder<Self> {
+        let span = self.span;
+        ExprBuilder::with_callback(self).span(span)
+    }
+
+    pub fn build(self) -> F::Result {
+        self.build_(None)
+    }
+
+    fn build_(mut self, expr: Option<P<ast::Expr>>) -> F::Result {
+        self.stmts.extend(expr.map(|expr| {
+            StmtBuilder::new().span(expr.span).build_expr(expr)
+        }));
+        self.callback.invoke(P(ast::Block {
+            stmts: self.stmts,
+            id: ast::DUMMY_NODE_ID,
+            rules: self.block_check_mode,
+            span: self.span,
+        }))
+    }
+}
+
+impl<F> Invoke<ast::Stmt> for BlockBuilder<F>
+    where F: Invoke<P<ast::Block>>,
+{
+    type Result = Self;
+
+    fn invoke(self, stmt: ast::Stmt) -> Self {
+        self.with_stmt(stmt)
+    }
+}
+
+impl<F> Invoke<P<ast::Expr>> for BlockBuilder<F>
+    where F: Invoke<P<ast::Block>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+        self.build_expr(expr)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/constant.rs
@@ -0,0 +1,88 @@
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span};
+use syntax::ptr::P;
+
+use expr::ExprBuilder;
+use invoke::{Invoke, Identity};
+use ty::TyBuilder;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct Const {
+    pub ty: P<ast::Ty>,
+    pub expr: Option<P<ast::Expr>>,
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ConstBuilder<F=Identity> {
+    callback: F,
+    span: Span,
+    expr: Option<P<ast::Expr>>,
+}
+
+impl ConstBuilder {
+    pub fn new() -> Self {
+        ConstBuilder::with_callback(Identity)
+    }
+}
+
+impl<F> ConstBuilder<F>
+    where F: Invoke<Const>,
+{
+    pub fn with_callback(callback: F) -> Self
+        where F: Invoke<Const>,
+    {
+        ConstBuilder {
+            callback: callback,
+            span: DUMMY_SP,
+            expr: None,
+        }
+    }
+
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn with_expr(mut self, expr: P<ast::Expr>) -> Self {
+        self.expr = Some(expr);
+        self
+    }
+
+    pub fn expr(self) -> ExprBuilder<Self> {
+        ExprBuilder::with_callback(self)
+    }
+
+    pub fn ty(self) -> TyBuilder<Self> {
+        let span = self.span;
+        TyBuilder::with_callback(self).span(span)
+    }
+
+    pub fn build(self, ty: P<ast::Ty>) -> F::Result {
+        self.callback.invoke(Const {
+            ty: ty,
+            expr: self.expr,
+        })
+    }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ConstBuilder<F>
+    where F: Invoke<Const>,
+{
+    type Result = Self;
+
+    fn invoke(self, expr: P<ast::Expr>) -> Self {
+        self.with_expr(expr)
+    }
+}
+
+impl<F> Invoke<P<ast::Ty>> for ConstBuilder<F>
+    where F: Invoke<Const>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, ty: P<ast::Ty>) -> F::Result {
+        self.build(ty)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/ctx.rs
@@ -0,0 +1,17 @@
+use syntax::ast;
+use syntax::parse::token;
+
+//////////////////////////////////////////////////////////////////////////////
+
+#[derive(Copy)]
+pub struct Ctx;
+
+impl Ctx {
+    pub fn new() -> Ctx {
+        Ctx
+    }
+
+    pub fn intern(&self, name: &str) -> ast::Name {
+        token::intern(name)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/expr.rs
@@ -0,0 +1,2181 @@
+#![cfg_attr(feature = "unstable-testing", allow(should_implement_trait))]
+
+use std::iter::IntoIterator;
+
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span, Spanned, respan};
+use syntax::ptr::P;
+
+use arm::ArmBuilder;
+use attr::AttrBuilder;
+use block::BlockBuilder;
+use fn_decl::FnDeclBuilder;
+use ident::ToIdent;
+use invoke::{Invoke, Identity};
+use lit::LitBuilder;
+use mac::MacBuilder;
+use pat::PatBuilder;
+use path::{IntoPath, PathBuilder};
+use qpath::QPathBuilder;
+use str::ToInternedString;
+use ty::TyBuilder;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprBuilder<F=Identity> {
+    callback: F,
+    span: Span,
+    attrs: Vec<ast::Attribute>,
+}
+
+impl ExprBuilder {
+    pub fn new() -> Self {
+        ExprBuilder::with_callback(Identity)
+    }
+}
+
+macro_rules! signed_int_method {
+    ($ty:ident, $unsigned:ident) => {
+        pub fn $ty(self, val: $ty) -> F::Result {
+            if val == ::std::$ty::MIN {
+                self.neg().lit().$ty(val as $unsigned)
+            } else if val < 0 {
+                self.neg().lit().$ty(-val as $unsigned)
+            } else {
+                self.lit().$ty(val as $unsigned)
+            }
+        }
+    };
+}
+
+impl<F> ExprBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    pub fn with_callback(callback: F) -> Self {
+        ExprBuilder {
+            callback: callback,
+            span: DUMMY_SP,
+            attrs: vec![],
+        }
+    }
+
+    pub fn build(self, expr: P<ast::Expr>) -> F::Result {
+        self.callback.invoke(expr)
+    }
+
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn with_attr(mut self, attr: ast::Attribute) -> Self {
+        self.attrs.push(attr);
+        self
+    }
+
+    pub fn attr(self) -> AttrBuilder<Self> {
+        AttrBuilder::with_callback(self)
+    }
+
+    pub fn build_expr_kind(self, expr: ast::ExprKind) -> F::Result {
+        let expr = P(ast::Expr {
+            id: ast::DUMMY_NODE_ID,
+            node: expr,
+            span: self.span,
+            attrs: self.attrs.clone().into(),
+        });
+        self.build(expr)
+    }
+
+    pub fn build_path(self, path: ast::Path) -> F::Result {
+        self.build_expr_kind(ast::ExprKind::Path(None, path))
+    }
+
+    pub fn build_qpath(self, qself: ast::QSelf, path: ast::Path) -> F::Result {
+        self.build_expr_kind(ast::ExprKind::Path(Some(qself), path))
+    }
+
+    pub fn path(self) -> PathBuilder<Self> {
+        let span = self.span;
+        PathBuilder::with_callback(self).span(span)
+    }
+
+    pub fn qpath(self) -> QPathBuilder<Self> {
+        let span = self.span;
+        QPathBuilder::with_callback(self).span(span)
+    }
+
+    pub fn id<I>(self, id: I) -> F::Result
+        where I: ToIdent
+    {
+        self.path().id(id).build()
+    }
+
+    pub fn build_lit(self, lit: P<ast::Lit>) -> F::Result {
+        self.build_expr_kind(ast::ExprKind::Lit(lit))
+    }
+
+    pub fn lit(self) -> LitBuilder<Self> {
+        LitBuilder::with_callback(self)
+    }
+
+    pub fn bool(self, value: bool) -> F::Result {
+        self.lit().bool(value)
+    }
+
+    pub fn true_(self) -> F::Result {
+        self.bool(true)
+    }
+
+    pub fn false_(self) -> F::Result {
+        self.bool(false)
+    }
+
+    pub fn int(self, value: i64) -> F::Result {
+        if value == ::std::i64::MIN {
+            self.neg().lit().int(value as u64)
+        } else if value < 0 {
+            self.neg().lit().int(-value as u64)
+        } else {
+            self.lit().int(value as u64)
+        }
+    }
+
+    pub fn uint(self, value: u64) -> F::Result {
+        self.lit().uint(value as u64)
+    }
+
+    signed_int_method!(i8, u8);
+    signed_int_method!(i16, u16);
+    signed_int_method!(i32, u32);
+    signed_int_method!(i64, u64);
+    signed_int_method!(isize, usize);
+
+    pub fn usize(self, value: usize) -> F::Result {
+        self.lit().usize(value)
+    }
+
+    pub fn u8(self, value: u8) -> F::Result {
+        self.lit().u8(value)
+    }
+
+    pub fn u16(self, value: u16) -> F::Result {
+        self.lit().u16(value)
+    }
+
+    pub fn u32(self, value: u32) -> F::Result {
+        self.lit().u32(value)
+    }
+
+    pub fn u64(self, value: u64) -> F::Result {
+        self.lit().u64(value)
+    }
+
+    pub fn f32<S>(self, value: S) -> F::Result
+        where S: ToInternedString,
+    {
+        self.lit().f32(value)
+    }
+
+    pub fn f64<S>(self, value: S) -> F::Result
+        where S: ToInternedString,
+    {
+        self.lit().f64(value)
+    }
+
+    pub fn str<S>(self, value: S) -> F::Result
+        where S: ToInternedString,
+    {
+        self.lit().str(value)
+    }
+
+    pub fn build_unary(self, unop: ast::UnOp, expr: P<ast::Expr>) -> F::Result {
+        self.build_expr_kind(ast::ExprKind::Unary(unop, expr))
+    }
+
+    pub fn build_deref(self, expr: P<ast::Expr>) -> F::Result {
+        self.build_unary(ast::UnOp::Deref, expr)
+    }
+
+    pub fn build_not(self, expr: P<ast::Expr>) -> F::Result {
+        self.build_unary(ast::UnOp::Not, expr)
+    }
+
+    pub fn build_neg(self, expr: P<ast::Expr>) -> F::Result {
+        self.build_unary(ast::UnOp::Neg, expr)
+    }
+
+    pub fn unary(self, unop: ast::UnOp) -> ExprBuilder<ExprUnaryBuilder<F>> {
+        let span = self.span;
+        ExprBuilder::with_callback(ExprUnaryBuilder {
+            builder: self,
+            unop: unop,
+        }).span(span)
+    }
+
+    pub fn deref(self) -> ExprBuilder<ExprUnaryBuilder<F>> {
+        self.unary(ast::UnOp::Deref)
+    }
+
+    pub fn not(self) -> ExprBuilder<ExprUnaryBuilder<F>> {
+        self.unary(ast::UnOp::Not)
+    }
+
+    pub fn neg(self) -> ExprBuilder<ExprUnaryBuilder<F>> {
+        self.unary(ast::UnOp::Neg)
+    }
+
+    pub fn build_binary(self,
+                        binop: ast::BinOpKind,
+                        lhs: P<ast::Expr>,
+                        rhs: P<ast::Expr>) -> F::Result {
+        let binop = respan(self.span, binop);
+        self.build_expr_kind(ast::ExprKind::Binary(binop, lhs, rhs))
+    }
+
+    pub fn build_add(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::Add, lhs, rhs)
+    }
+
+    pub fn build_sub(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::Sub, lhs, rhs)
+    }
+
+    pub fn build_mul(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::Mul, lhs, rhs)
+    }
+
+    pub fn build_div(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::Div, lhs, rhs)
+    }
+
+    pub fn build_rem(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::Rem, lhs, rhs)
+    }
+
+    pub fn build_and(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::And, lhs, rhs)
+    }
+
+    pub fn build_or(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::Or, lhs, rhs)
+    }
+
+    pub fn build_bit_xor(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::BitXor, lhs, rhs)
+    }
+
+    pub fn build_bit_and(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::BitAnd, lhs, rhs)
+    }
+
+    pub fn build_bit_or(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::BitOr, lhs, rhs)
+    }
+
+    pub fn build_shl(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::Shl, lhs, rhs)
+    }
+
+    pub fn build_shr(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::Shr, lhs, rhs)
+    }
+
+    pub fn build_eq(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::Eq, lhs, rhs)
+    }
+
+    pub fn build_lt(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::Lt, lhs, rhs)
+    }
+
+    pub fn build_le(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::Le, lhs, rhs)
+    }
+
+    pub fn build_ne(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::Ne, lhs, rhs)
+    }
+
+    pub fn build_ge(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::Ge, lhs, rhs)
+    }
+
+    pub fn build_gt(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_binary(ast::BinOpKind::Gt, lhs, rhs)
+    }
+
+    pub fn binary(self, binop: ast::BinOpKind) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        let span = self.span;
+        ExprBuilder::with_callback(ExprBinaryLhsBuilder {
+            builder: self,
+            binop: binop,
+        }).span(span)
+    }
+
+    pub fn add(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::Add)
+    }
+
+    pub fn sub(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::Sub)
+    }
+
+    pub fn mul(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::Mul)
+    }
+
+    pub fn div(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::Div)
+    }
+
+    pub fn rem(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::Rem)
+    }
+
+    pub fn and(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::And)
+    }
+
+    pub fn or(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::Or)
+    }
+
+    pub fn bit_xor(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::BitXor)
+    }
+
+    pub fn bit_and(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::BitAnd)
+    }
+
+    pub fn bit_or(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::BitOr)
+    }
+
+    pub fn shl(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::Shl)
+    }
+
+    pub fn shr(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::Shr)
+    }
+
+    pub fn eq(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::Eq)
+    }
+
+    pub fn lt(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::Lt)
+    }
+
+    pub fn le(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::Le)
+    }
+
+    pub fn ne(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::Ne)
+    }
+
+    pub fn ge(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::Ge)
+    }
+
+    pub fn gt(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+        self.binary(ast::BinOpKind::Gt)
+    }
+
+    pub fn ref_(self) -> ExprBuilder<ExprRefBuilder<F>> {
+        let span = self.span;
+        ExprBuilder::with_callback(ExprRefBuilder {
+            builder: self,
+            mutability: ast::Mutability::Immutable,
+        }).span(span)
+    }
+
+    pub fn mut_ref(self) -> ExprBuilder<ExprRefBuilder<F>> {
+        let span = self.span;
+        ExprBuilder::with_callback(ExprRefBuilder {
+            builder: self,
+            mutability: ast::Mutability::Mutable,
+        }).span(span)
+    }
+
+    pub fn break_(self) -> F::Result {
+        self.build_expr_kind(ast::ExprKind::Break(None))
+    }
+
+    pub fn break_to<I>(self, label: I) -> F::Result
+        where I: ToIdent,
+    {
+        let label = respan(self.span, label.to_ident());
+        self.build_expr_kind(ast::ExprKind::Break(Some(label)))
+    }
+
+    pub fn continue_(self) -> F::Result {
+        self.build_expr_kind(ast::ExprKind::Continue(None))
+    }
+
+    pub fn continue_to<I>(self, label: I) -> F::Result
+        where I: ToIdent,
+    {
+        let label = respan(self.span, label.to_ident());
+        self.build_expr_kind(ast::ExprKind::Continue(Some(label)))
+    }
+
+    pub fn return_(self) -> F::Result {
+        self.build_expr_kind(ast::ExprKind::Ret(None))
+    }
+
+    pub fn return_expr(self) -> ExprBuilder<ExprReturnBuilder<F>> {
+        let span = self.span;
+        ExprBuilder::with_callback(ExprReturnBuilder {
+            builder: self,
+        }).span(span)
+    }
+
+    pub fn unit(self) -> F::Result {
+        self.tuple().build()
+    }
+
+    pub fn tuple(self) -> ExprTupleBuilder<F> {
+        ExprTupleBuilder {
+            builder: self,
+            exprs: Vec::new(),
+        }
+    }
+
+    pub fn struct_path<P>(self, path: P) -> ExprStructPathBuilder<F>
+        where P: IntoPath,
+    {
+        let span = self.span;
+        let path = path.into_path();
+        ExprStructPathBuilder {
+            builder: self,
+            span: span,
+            path: path,
+            fields: vec![],
+        }
+    }
+
+    pub fn struct_id<T>(self, id: T) -> ExprStructPathBuilder<F>
+        where T: ToIdent,
+    {
+        self.struct_().id(id).build()
+    }
+
+    pub fn struct_(self) -> PathBuilder<ExprStructBuilder<F>> {
+        PathBuilder::with_callback(ExprStructBuilder {
+            builder: self,
+        })
+    }
+
+    pub fn self_(self) -> F::Result {
+        self.id("self")
+    }
+
+    pub fn none(self) -> F::Result {
+        self.path()
+            .global()
+            .id("std").id("option").id("Option").id("None")
+            .build()
+    }
+
+    pub fn some(self) -> ExprBuilder<ExprPathBuilder<F>> {
+        let path = PathBuilder::new()
+            .span(self.span)
+            .global()
+            .id("std").id("option").id("Option").id("Some")
+            .build();
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprPathBuilder {
+            builder: self,
+            path: path,
+        }).span(span)
+    }
+
+    pub fn ok(self) -> ExprBuilder<ExprPathBuilder<F>> {
+        let path = PathBuilder::new()
+            .span(self.span)
+            .global()
+            .id("std").id("result").id("Result").id("Ok")
+            .build();
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprPathBuilder {
+            builder: self,
+            path: path,
+        }).span(span)
+    }
+
+    pub fn err(self) -> ExprBuilder<ExprPathBuilder<F>> {
+        let path = PathBuilder::new()
+            .span(self.span)
+            .global()
+            .id("std").id("result").id("Result").id("Err")
+            .build();
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprPathBuilder {
+            builder: self,
+            path: path,
+        }).span(span)
+    }
+
+    /// Implement a call for `::std::convert::From::from(value)`
+    pub fn from(self) -> ExprBuilder<ExprPathBuilder<F>> {
+        let path = PathBuilder::new()
+            .span(self.span)
+            .global()
+            .ids(&["std", "convert", "From", "from"])
+            .build();
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprPathBuilder {
+            builder: self,
+            path: path,
+        }).span(span)
+    }
+
+    pub fn phantom_data(self) -> F::Result {
+        self.path()
+            .global()
+            .ids(&["std", "marker", "PhantomData"])
+            .build()
+    }
+
+    pub fn call(self) -> ExprBuilder<ExprCallBuilder<F>> {
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprCallBuilder {
+            builder: self,
+        }).span(span)
+    }
+
+    pub fn method_call<I>(self, id: I) -> ExprBuilder<ExprMethodCallBuilder<F>>
+        where I: ToIdent,
+    {
+        let id = respan(self.span, id.to_ident());
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprMethodCallBuilder {
+            builder: self,
+            id: id,
+        }).span(span)
+    }
+
+    pub fn build_block(self, block: P<ast::Block>) -> F::Result {
+        self.build_expr_kind(ast::ExprKind::Block(block))
+    }
+
+    pub fn block(self) -> BlockBuilder<Self> {
+        BlockBuilder::with_callback(self)
+    }
+
+    pub fn build_assign(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_expr_kind(ast::ExprKind::Assign(lhs, rhs))
+    }
+
+    pub fn assign(self) -> ExprBuilder<ExprAssignBuilder<F>> {
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprAssignBuilder {
+            builder: self,
+        }).span(span)
+    }
+
+    pub fn build_assign_op(self,
+                           binop: ast::BinOpKind,
+                           lhs: P<ast::Expr>,
+                           rhs: P<ast::Expr>) -> F::Result {
+        let binop = respan(self.span, binop);
+        self.build_expr_kind(ast::ExprKind::AssignOp(binop, lhs, rhs))
+    }
+
+    pub fn assign_op(self, binop: ast::BinOpKind) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprAssignOpBuilder {
+            builder: self,
+            binop: binop,
+        }).span(span)
+    }
+
+    pub fn add_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+        self.assign_op(ast::BinOpKind::Add)
+    }
+
+    pub fn sub_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+        self.assign_op(ast::BinOpKind::Sub)
+    }
+
+    pub fn mul_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+        self.assign_op(ast::BinOpKind::Mul)
+    }
+
+    pub fn rem_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+        self.assign_op(ast::BinOpKind::Rem)
+    }
+
+    pub fn and_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+        self.assign_op(ast::BinOpKind::And)
+    }
+
+    pub fn or_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+        self.assign_op(ast::BinOpKind::Or)
+    }
+
+    pub fn bit_xor_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+        self.assign_op(ast::BinOpKind::BitXor)
+    }
+
+    pub fn bit_and_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+        self.assign_op(ast::BinOpKind::BitAnd)
+    }
+
+    pub fn bit_or_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+        self.assign_op(ast::BinOpKind::BitOr)
+    }
+
+    pub fn bit_shl_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+        self.assign_op(ast::BinOpKind::Shl)
+    }
+
+    pub fn bit_shr_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+        self.assign_op(ast::BinOpKind::Shr)
+    }
+
+    pub fn build_index(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_expr_kind(ast::ExprKind::Index(lhs, rhs))
+    }
+
+    pub fn index(self) -> ExprBuilder<ExprIndexBuilder<F>> {
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprIndexBuilder {
+            builder: self,
+        }).span(span)
+    }
+
+    pub fn range(self) -> ExprRangeBuilder<F> {
+        ExprRangeBuilder {
+            builder: self,
+        }
+    }
+
+    pub fn build_repeat(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_expr_kind(ast::ExprKind::Repeat(lhs, rhs))
+    }
+
+    pub fn repeat(self) -> ExprBuilder<ExprRepeatBuilder<F>> {
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprRepeatBuilder {
+            builder: self,
+        }).span(span)
+    }
+
+    pub fn loop_(self) -> ExprLoopBuilder<F> {
+        let span = self.span;
+
+        ExprLoopBuilder {
+            builder: self,
+            span: span,
+            label: None,
+        }
+    }
+
+    pub fn if_(self) -> ExprBuilder<ExprIfBuilder<F>> {
+        let span = self.span;
+        ExprBuilder::with_callback(ExprIfBuilder {
+            builder: self,
+        }).span(span)
+    }
+
+    pub fn match_(self) -> ExprBuilder<ExprMatchBuilder<F>> {
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprMatchBuilder {
+            builder: self,
+        }).span(span)
+    }
+
+    pub fn paren(self) -> ExprBuilder<ExprParenBuilder<F>> {
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprParenBuilder {
+            builder: self,
+        }).span(span)
+    }
+
+    pub fn field<I>(self, id: I) -> ExprBuilder<ExprFieldBuilder<F>>
+        where I: ToIdent,
+    {
+        let id = respan(self.span, id.to_ident());
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprFieldBuilder {
+            builder: self,
+            id: id,
+        }).span(span)
+    }
+
+    pub fn tup_field(self, index: usize) -> ExprBuilder<ExprTupFieldBuilder<F>> {
+        let index = respan(self.span, index);
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprTupFieldBuilder {
+            builder: self,
+            index: index,
+        }).span(span)
+    }
+
+    pub fn box_(self) -> ExprBuilder<ExprPathBuilder<F>> {
+        let path = PathBuilder::new()
+            .span(self.span)
+            .global()
+            .id("std").id("boxed").id("Box").id("new")
+            .build();
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprPathBuilder {
+            builder: self,
+            path: path,
+        }).span(span)
+    }
+
+    pub fn rc(self) -> ExprBuilder<ExprPathBuilder<F>> {
+        let path = PathBuilder::new()
+            .span(self.span)
+            .global()
+            .id("std").id("rc").id("Rc").id("new")
+            .build();
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprPathBuilder {
+            builder: self,
+            path: path,
+        }).span(span)
+    }
+
+    pub fn arc(self) -> ExprBuilder<ExprPathBuilder<F>> {
+        let path = PathBuilder::new()
+            .span(self.span)
+            .global()
+            .id("std").id("arc").id("Arc").id("new")
+            .build();
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprPathBuilder {
+            builder: self,
+            path: path,
+        }).span(span)
+    }
+
+    pub fn default(self) -> F::Result {
+        let path = PathBuilder::new()
+            .span(self.span)
+            .global()
+            .ids(&["std", "default", "Default", "default"])
+            .build();
+
+        self.call()
+            .build_path(path)
+            .build()
+    }
+
+    pub fn slice(self) -> ExprSliceBuilder<F> {
+        ExprSliceBuilder {
+            builder: self,
+            exprs: Vec::new(),
+        }
+    }
+
+    pub fn vec(self) -> ExprSliceBuilder<ExprVecBuilder<F>> {
+        ExprBuilder::with_callback(ExprVecBuilder {
+            builder: self,
+        }).slice()
+    }
+
+    /// Represents an equivalent to `try!(...)`. Generates:
+    ///
+    /// match $expr {
+    ///     ::std::result::Result::Ok(expr) => expr,
+    ///     ::std::result::Result::Err(err) => {
+    ///         return ::std::result::Result::Err(::std::convert::From::from(err))
+    ///     }
+    /// }
+    pub fn try(self) -> ExprBuilder<ExprTryBuilder<F>> {
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprTryBuilder {
+            builder: self,
+        }).span(span)
+    }
+
+    pub fn closure(self) -> ExprClosureBuilder<F> {
+        ExprClosureBuilder {
+            span: self.span,
+            builder: self,
+            capture_by: ast::CaptureBy::Ref,
+        }
+    }
+
+    pub fn while_(self) -> ExprBuilder<ExprWhileBuilder<F>> {
+        ExprBuilder::with_callback(ExprWhileBuilder {
+            builder: self,
+        })
+    }
+
+    pub fn type_(self) -> ExprBuilder<ExprTypeBuilder<F>> {
+        ExprBuilder::with_callback(ExprTypeBuilder {
+            builder: self,
+        })
+    }
+
+    pub fn build_mac(self, mac: ast::Mac) -> F::Result {
+        self.build_expr_kind(ast::ExprKind::Mac(mac))
+    }
+
+    pub fn mac(self) -> MacBuilder<Self> {
+        let span = self.span;
+        MacBuilder::with_callback(self).span(span)
+    }
+}
+
+impl<F> Invoke<ast::Attribute> for ExprBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = Self;
+
+    fn invoke(self, attr: ast::Attribute) -> Self {
+        self.with_attr(attr)
+    }
+}
+
+impl<F> Invoke<P<ast::Lit>> for ExprBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, lit: P<ast::Lit>) -> F::Result {
+        self.build_lit(lit)
+    }
+}
+
+impl<F> Invoke<ast::Path> for ExprBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, path: ast::Path) -> F::Result {
+        self.build_path(path)
+    }
+}
+
+impl<F> Invoke<(ast::QSelf, ast::Path)> for ExprBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, (qself, path): (ast::QSelf, ast::Path)) -> F::Result {
+        self.build_qpath(qself, path)
+    }
+}
+
+impl<F> Invoke<P<ast::Block>> for ExprBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, block: P<ast::Block>) -> F::Result {
+        self.build_block(block)
+    }
+}
+
+impl<F> Invoke<ast::Mac> for ExprBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, mac: ast::Mac) -> F::Result {
+        self.build_mac(mac)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprUnaryBuilder<F> {
+    builder: ExprBuilder<F>,
+    unop: ast::UnOp,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprUnaryBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+        self.builder.build_unary(self.unop, expr)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprBinaryLhsBuilder<F> {
+    builder: ExprBuilder<F>,
+    binop: ast::BinOpKind,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprBinaryLhsBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = ExprBuilder<ExprBinaryRhsBuilder<F>>;
+
+    fn invoke(self, lhs: P<ast::Expr>) -> ExprBuilder<ExprBinaryRhsBuilder<F>> {
+        ExprBuilder::with_callback(ExprBinaryRhsBuilder {
+            builder: self.builder,
+            binop: self.binop,
+            lhs: lhs,
+        })
+    }
+}
+
+pub struct ExprBinaryRhsBuilder<F> {
+    builder: ExprBuilder<F>,
+    binop: ast::BinOpKind,
+    lhs: P<ast::Expr>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprBinaryRhsBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, rhs: P<ast::Expr>) -> F::Result {
+        self.builder.build_binary(self.binop, self.lhs, rhs)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprReturnBuilder<F> {
+    builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprReturnBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+        self.builder.build_expr_kind(ast::ExprKind::Ret(Some(expr)))
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprTupleBuilder<F> {
+    builder: ExprBuilder<F>,
+    exprs: Vec<P<ast::Expr>>,
+}
+
+impl<F: Invoke<P<ast::Expr>>> ExprTupleBuilder<F>
+    where F: Invoke<P<ast::Expr>>
+{
+    pub fn with_exprs<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=P<ast::Expr>>,
+    {
+        self.exprs.extend(iter);
+        self
+    }
+
+    pub fn expr(self) -> ExprBuilder<Self> {
+        ExprBuilder::with_callback(self)
+    }
+
+    pub fn build(self) -> F::Result {
+        self.builder.build_expr_kind(ast::ExprKind::Tup(self.exprs))
+    }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprTupleBuilder<F>
+    where F: Invoke<P<ast::Expr>>
+{
+    type Result = ExprTupleBuilder<F>;
+
+    fn invoke(mut self, expr: P<ast::Expr>) -> Self {
+        self.exprs.push(expr);
+        self
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprStructBuilder<F> {
+    builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<ast::Path> for ExprStructBuilder<F>
+    where F: Invoke<P<ast::Expr>>
+{
+    type Result = ExprStructPathBuilder<F>;
+
+    fn invoke(self, path: ast::Path) -> ExprStructPathBuilder<F> {
+        self.builder.struct_path(path)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprStructPathBuilder<F> {
+    builder: ExprBuilder<F>,
+    span: Span,
+    path: ast::Path,
+    fields: Vec<ast::Field>,
+}
+
+impl<F> ExprStructPathBuilder<F>
+    where F: Invoke<P<ast::Expr>>
+{
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn with_fields<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=ast::Field>,
+    {
+        self.fields.extend(iter);
+        self
+    }
+
+    pub fn with_id_exprs<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=(ast::Ident, P<ast::Expr>)>,
+    {
+        for (id, expr) in iter {
+            self = self.field(id).build(expr);
+        }
+
+        self
+    }
+
+    pub fn field<I>(self, id: I) -> ExprBuilder<ExprStructFieldBuilder<I, F>>
+        where I: ToIdent,
+    {
+        let span = self.span;
+
+        ExprBuilder::with_callback(ExprStructFieldBuilder {
+            builder: self,
+            id: id,
+        }).span(span)
+    }
+
+    pub fn build_with(self) -> ExprBuilder<Self> {
+        ExprBuilder::with_callback(self)
+    }
+
+    pub fn build(self) -> F::Result {
+        let expr_kind = ast::ExprKind::Struct(self.path, self.fields, None);
+        self.builder.build_expr_kind(expr_kind)
+    }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprStructPathBuilder<F>
+    where F: Invoke<P<ast::Expr>>
+{
+    type Result = F::Result;
+
+    fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+        let expr_kind = ast::ExprKind::Struct(self.path, self.fields, Some(expr));
+        self.builder.build_expr_kind(expr_kind)
+    }
+}
+
+pub struct ExprStructFieldBuilder<I, F> {
+    builder: ExprStructPathBuilder<F>,
+    id: I,
+}
+
+impl<I, F> Invoke<P<ast::Expr>> for ExprStructFieldBuilder<I, F>
+    where I: ToIdent,
+          F: Invoke<P<ast::Expr>>,
+{
+    type Result = ExprStructPathBuilder<F>;
+
+    fn invoke(mut self, expr: P<ast::Expr>) -> ExprStructPathBuilder<F> {
+        let field = ast::Field {
+            ident: respan(self.builder.span, self.id.to_ident()),
+            expr: expr,
+            span: self.builder.span,
+            is_shorthand: false,
+        };
+        self.builder.fields.push(field);
+        self.builder
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprCallBuilder<F> {
+    builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprCallBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = ExprCallArgsBuilder<F>;
+
+    fn invoke(self, expr: P<ast::Expr>) -> ExprCallArgsBuilder<F> {
+        ExprCallArgsBuilder {
+            builder: self.builder,
+            fn_: expr,
+            args: vec![],
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprCallArgsBuilder<F> {
+    builder: ExprBuilder<F>,
+    fn_: P<ast::Expr>,
+    args: Vec<P<ast::Expr>>,
+}
+
+impl<F> ExprCallArgsBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    pub fn with_args<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=P<ast::Expr>>,
+    {
+        self.args.extend(iter);
+        self
+    }
+
+    pub fn with_arg(mut self, arg: P<ast::Expr>) -> Self {
+        self.args.push(arg);
+        self
+    }
+
+    pub fn arg(self) -> ExprBuilder<Self> {
+        let span = self.builder.span;
+        ExprBuilder::with_callback(self).span(span)
+    }
+
+    pub fn build(self) -> F::Result {
+        self.builder.build_expr_kind(ast::ExprKind::Call(self.fn_, self.args))
+    }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprCallArgsBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = Self;
+
+    fn invoke(self, arg: P<ast::Expr>) -> Self {
+        self.with_arg(arg)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprMethodCallBuilder<F> {
+    builder: ExprBuilder<F>,
+    id: ast::SpannedIdent,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprMethodCallBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = ExprMethodCallArgsBuilder<F>;
+
+    fn invoke(self, expr: P<ast::Expr>) -> ExprMethodCallArgsBuilder<F> {
+        ExprMethodCallArgsBuilder {
+            builder: self.builder,
+            id: self.id,
+            tys: vec![],
+            args: vec![expr],
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprMethodCallArgsBuilder<F> {
+    builder: ExprBuilder<F>,
+    id: ast::SpannedIdent,
+    tys: Vec<P<ast::Ty>>,
+    args: Vec<P<ast::Expr>>,
+}
+
+impl<F> ExprMethodCallArgsBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    pub fn with_tys<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=P<ast::Ty>>,
+    {
+        self.tys.extend(iter);
+        self
+    }
+
+    pub fn with_ty(mut self, ty: P<ast::Ty>) -> Self {
+        self.tys.push(ty);
+        self
+    }
+
+    pub fn ty(self) -> TyBuilder<Self> {
+        let span = self.builder.span;
+        TyBuilder::with_callback(self).span(span)
+    }
+
+    pub fn with_args<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=P<ast::Expr>>,
+    {
+        self.args.extend(iter);
+        self
+    }
+
+    pub fn with_arg(mut self, arg: P<ast::Expr>) -> Self {
+        self.args.push(arg);
+        self
+    }
+
+    pub fn arg(self) -> ExprBuilder<Self> {
+        let span = self.builder.span;
+        ExprBuilder::with_callback(self).span(span)
+    }
+
+    pub fn build(self) -> F::Result {
+        self.builder.build_expr_kind(ast::ExprKind::MethodCall(self.id, self.tys, self.args))
+    }
+}
+
+impl<F> Invoke<P<ast::Ty>> for ExprMethodCallArgsBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = Self;
+
+    fn invoke(self, ty: P<ast::Ty>) -> Self {
+        self.with_ty(ty)
+    }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprMethodCallArgsBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = Self;
+
+    fn invoke(self, arg: P<ast::Expr>) -> Self {
+        self.with_arg(arg)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprRefBuilder<F> {
+    builder: ExprBuilder<F>,
+    mutability: ast::Mutability,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprRefBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+        self.builder.build_expr_kind(ast::ExprKind::AddrOf(self.mutability, expr))
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprPathBuilder<F> {
+    builder: ExprBuilder<F>,
+    path: ast::Path,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprPathBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, arg: P<ast::Expr>) -> F::Result {
+        self.builder.call()
+            .build_path(self.path)
+            .with_arg(arg)
+            .build()
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprAssignBuilder<F> {
+    builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprAssignBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = ExprBuilder<ExprAssignLhsBuilder<F>>;
+
+    fn invoke(self, lhs: P<ast::Expr>) -> ExprBuilder<ExprAssignLhsBuilder<F>> {
+        let span = self.builder.span;
+        ExprBuilder::with_callback(ExprAssignLhsBuilder {
+            builder: self.builder,
+            lhs: lhs,
+        }).span(span)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprAssignLhsBuilder<F> {
+    builder: ExprBuilder<F>,
+    lhs: P<ast::Expr>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprAssignLhsBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, rhs: P<ast::Expr>) -> F::Result {
+        self.builder.build_assign(self.lhs, rhs)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprAssignOpBuilder<F> {
+    builder: ExprBuilder<F>,
+    binop: ast::BinOpKind,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprAssignOpBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = ExprBuilder<ExprAssignOpLhsBuilder<F>>;
+
+    fn invoke(self, lhs: P<ast::Expr>) -> ExprBuilder<ExprAssignOpLhsBuilder<F>> {
+        let span = self.builder.span;
+        ExprBuilder::with_callback(ExprAssignOpLhsBuilder {
+            builder: self.builder,
+            binop: self.binop,
+            lhs: lhs,
+        }).span(span)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprAssignOpLhsBuilder<F> {
+    builder: ExprBuilder<F>,
+    binop: ast::BinOpKind,
+    lhs: P<ast::Expr>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprAssignOpLhsBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, rhs: P<ast::Expr>) -> F::Result {
+        self.builder.build_assign_op(self.binop, self.lhs, rhs)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprIndexBuilder<F> {
+    builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprIndexBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = ExprBuilder<ExprIndexLhsBuilder<F>>;
+
+    fn invoke(self, lhs: P<ast::Expr>) -> ExprBuilder<ExprIndexLhsBuilder<F>> {
+        let span = self.builder.span;
+        ExprBuilder::with_callback(ExprIndexLhsBuilder {
+            builder: self.builder,
+            lhs: lhs,
+        }).span(span)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprIndexLhsBuilder<F> {
+    builder: ExprBuilder<F>,
+    lhs: P<ast::Expr>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprIndexLhsBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, rhs: P<ast::Expr>) -> F::Result {
+        self.builder.build_index(self.lhs, rhs)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprRangeBuilder<F> {
+    builder: ExprBuilder<F>,
+}
+
+impl<F> ExprRangeBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    pub fn from(self) -> ExprBuilder<Self> {
+        ExprBuilder::with_callback(self)
+    }
+
+    pub fn to(self) -> ExprBuilder<ExprRangeToBuilder<F>> {
+        self.from_opt(None).to()
+    }
+
+    pub fn to_inclusive(self) -> ExprBuilder<ExprRangeToBuilder<F>> {
+        self.from_opt(None).to_inclusive()
+    }
+
+    pub fn from_opt(self, from: Option<P<ast::Expr>>) -> ExprRangeFromBuilder<F> {
+        ExprRangeFromBuilder {
+            builder: self.builder,
+            from: from,
+        }
+    }
+
+    pub fn build(self) -> F::Result {
+        self.from_opt(None).build()
+    }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprRangeBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = ExprRangeFromBuilder<F>;
+
+    fn invoke(self, from: P<ast::Expr>) -> ExprRangeFromBuilder<F> {
+        self.from_opt(Some(from))
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprRangeFromBuilder<F> {
+    builder: ExprBuilder<F>,
+    from: Option<P<ast::Expr>>,
+}
+
+impl<F> ExprRangeFromBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    pub fn to(self) -> ExprBuilder<ExprRangeToBuilder<F>> {
+        ExprBuilder::with_callback(ExprRangeToBuilder {
+            builder: self,
+            limit: ast::RangeLimits::HalfOpen,
+        })
+    }
+
+    pub fn to_inclusive(self) -> ExprBuilder<ExprRangeToBuilder<F>> {
+        ExprBuilder::with_callback(ExprRangeToBuilder {
+            builder: self,
+            limit: ast::RangeLimits::Closed,
+        })
+    }
+
+    pub fn build(self) -> F::Result {
+        self.to_opt(None, ast::RangeLimits::HalfOpen)
+    }
+
+    pub fn to_opt(self, to: Option<P<ast::Expr>>, limit: ast::RangeLimits) -> F::Result {
+        let kind = ast::ExprKind::Range(self.from, to, limit);
+        self.builder.build_expr_kind(kind)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprRangeToBuilder<F> {
+    builder: ExprRangeFromBuilder<F>,
+    limit: ast::RangeLimits,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprRangeToBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+        self.builder.to_opt(Some(expr), self.limit)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprRepeatBuilder<F> {
+    builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprRepeatBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = ExprBuilder<ExprRepeatLhsBuilder<F>>;
+
+    fn invoke(self, lhs: P<ast::Expr>) -> ExprBuilder<ExprRepeatLhsBuilder<F>> {
+        let span = self.builder.span;
+        ExprBuilder::with_callback(ExprRepeatLhsBuilder {
+            builder: self.builder,
+            lhs: lhs,
+        }).span(span)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprRepeatLhsBuilder<F> {
+    builder: ExprBuilder<F>,
+    lhs: P<ast::Expr>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprRepeatLhsBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, rhs: P<ast::Expr>) -> F::Result {
+        self.builder.build_repeat(self.lhs, rhs)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprLoopBuilder<F> {
+    builder: ExprBuilder<F>,
+    span: Span,
+    label: Option<Spanned<ast::Ident>>,
+}
+
+impl<F> ExprLoopBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn label<I>(mut self, id: I) -> Self
+        where I: ToIdent,
+    {
+        self.label = Some(respan(self.span, id.to_ident()));
+        self
+    }
+
+    pub fn block(self) -> BlockBuilder<Self> {
+        BlockBuilder::with_callback(self)
+    }
+}
+
+impl<F> Invoke<P<ast::Block>> for ExprLoopBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, block: P<ast::Block>) -> F::Result {
+        self.builder.build_expr_kind(ast::ExprKind::Loop(block, self.label))
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprIfBuilder<F> {
+    builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprIfBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = ExprIfThenBuilder<F>;
+
+    fn invoke(self, condition: P<ast::Expr>) -> ExprIfThenBuilder<F> {
+        ExprIfThenBuilder {
+            builder: self.builder,
+            condition: condition,
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprIfThenBuilder<F> {
+    builder: ExprBuilder<F>,
+    condition: P<ast::Expr>,
+}
+
+impl<F> ExprIfThenBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    pub fn build_then(self, block: P<ast::Block>) -> ExprIfThenElseBuilder<F> {
+        ExprIfThenElseBuilder {
+            builder: self.builder,
+            condition: self.condition,
+            then: block,
+            else_ifs: Vec::new(),
+        }
+    }
+
+    pub fn then(self) -> BlockBuilder<Self> {
+        BlockBuilder::with_callback(self)
+    }
+}
+
+impl<F> Invoke<P<ast::Block>> for ExprIfThenBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = ExprIfThenElseBuilder<F>;
+
+    fn invoke(self, block: P<ast::Block>) -> ExprIfThenElseBuilder<F> {
+        self.build_then(block)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprIfThenElseBuilder<F> {
+    builder: ExprBuilder<F>,
+    condition: P<ast::Expr>,
+    then: P<ast::Block>,
+    else_ifs: Vec<(P<ast::Expr>, P<ast::Block>)>,
+}
+
+impl<F> ExprIfThenElseBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    pub fn else_if(self) -> ExprBuilder<ExprElseIfBuilder<F>> {
+        let span = self.builder.span;
+        ExprBuilder::with_callback(ExprElseIfBuilder {
+            builder: self,
+        }).span(span)
+    }
+
+    fn build_else_expr(self, mut else_: P<ast::Expr>) -> F::Result {
+        for (cond, block) in self.else_ifs.into_iter().rev() {
+            else_ = ExprBuilder::new().if_()
+                .build(cond)
+                .build_then(block)
+                .build_else_expr(else_);
+        }
+
+        self.builder.build_expr_kind(ast::ExprKind::If(self.condition, self.then, Some(else_)))
+    }
+
+    pub fn build_else(self, block: P<ast::Block>) -> F::Result {
+        let else_ = ExprBuilder::new().build_block(block);
+        self.build_else_expr(else_)
+    }
+
+    pub fn else_(self) -> BlockBuilder<Self> {
+        BlockBuilder::with_callback(self)
+    }
+
+    pub fn build(self) -> F::Result {
+        let mut else_ifs = self.else_ifs.into_iter().rev();
+
+        let else_ = match else_ifs.next() {
+            Some((cond, block)) => {
+                let mut else_ = ExprBuilder::new().if_()
+                    .build(cond)
+                    .build_then(block)
+                    .build();
+
+                for (cond, block) in else_ifs.into_iter().rev() {
+                    else_ = ExprBuilder::new().if_()
+                        .build(cond)
+                        .build_then(block)
+                        .build_else_expr(else_);
+                }
+
+                Some(else_)
+            }
+            None => None
+        };
+
+        self.builder.build_expr_kind(ast::ExprKind::If(self.condition, self.then, else_))
+    }
+}
+
+impl<F> Invoke<P<ast::Block>> for ExprIfThenElseBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, block: P<ast::Block>) -> F::Result {
+        self.build_else(block)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprElseIfBuilder<F> {
+    builder: ExprIfThenElseBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprElseIfBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = ExprElseIfThenBuilder<F>;
+
+    fn invoke(self, expr: P<ast::Expr>) -> ExprElseIfThenBuilder<F> {
+        ExprElseIfThenBuilder {
+            builder: self.builder,
+            condition: expr,
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprElseIfThenBuilder<F> {
+    builder: ExprIfThenElseBuilder<F>,
+    condition: P<ast::Expr>,
+}
+
+impl<F> ExprElseIfThenBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    pub fn build_then(mut self, block: P<ast::Block>) -> ExprIfThenElseBuilder<F> {
+        self.builder.else_ifs.push((self.condition, block));
+        self.builder
+    }
+
+    pub fn then(self) -> BlockBuilder<Self> {
+        BlockBuilder::with_callback(self)
+    }
+}
+
+impl<F> Invoke<P<ast::Block>> for ExprElseIfThenBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = ExprIfThenElseBuilder<F>;
+
+    fn invoke(self, block: P<ast::Block>) -> ExprIfThenElseBuilder<F> {
+        self.build_then(block)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprMatchBuilder<F> {
+    builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprMatchBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = ExprMatchArmBuilder<F>;
+
+    fn invoke(self, expr: P<ast::Expr>) -> ExprMatchArmBuilder<F> {
+        ExprMatchArmBuilder {
+            builder: self.builder,
+            expr: expr,
+            arms: Vec::new(),
+        }
+    }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprMatchArmBuilder<F> {
+    builder: ExprBuilder<F>,
+    expr: P<ast::Expr>,
+    arms: Vec<ast::Arm>,
+}
+
+impl<F> ExprMatchArmBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    pub fn with_arms<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=ast::Arm>,
+    {
+        self.arms.extend(iter);
+        self
+    }
+
+    pub fn with_arm(mut self, arm: ast::Arm) -> Self {
+        self.arms.push(arm);
+        self
+    }
+
+    pub fn arm(self) -> ArmBuilder<Self> {
+        ArmBuilder::with_callback(self)
+    }
+
+    pub fn build(self) -> F::Result {
+        self.builder.build_expr_kind(ast::ExprKind::Match(self.expr, self.arms))
+    }
+}
+
+impl<F> Invoke<ast::Arm> for ExprMatchArmBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = Self;
+
+    fn invoke(self, arm: ast::Arm) -> Self {
+        self.with_arm(arm)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprParenBuilder<F> {
+    builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprParenBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+        self.builder.build_expr_kind(ast::ExprKind::Paren(expr))
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprFieldBuilder<F> {
+    builder: ExprBuilder<F>,
+    id: ast::SpannedIdent,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprFieldBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+        self.builder.build_expr_kind(ast::ExprKind::Field(expr, self.id))
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprTupFieldBuilder<F> {
+    builder: ExprBuilder<F>,
+    index: Spanned<usize>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprTupFieldBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+        self.builder.build_expr_kind(ast::ExprKind::TupField(expr, self.index))
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprSliceBuilder<F> {
+    builder: ExprBuilder<F>,
+    exprs: Vec<P<ast::Expr>>,
+}
+
+impl<F: Invoke<P<ast::Expr>>> ExprSliceBuilder<F>
+    where F: Invoke<P<ast::Expr>>
+{
+    pub fn with_exprs<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=P<ast::Expr>>,
+    {
+        self.exprs.extend(iter);
+        self
+    }
+
+    pub fn expr(self) -> ExprBuilder<Self> {
+        let span = self.builder.span;
+        ExprBuilder::with_callback(self).span(span)
+    }
+
+    pub fn build(self) -> F::Result {
+        self.builder.build_expr_kind(ast::ExprKind::Vec(self.exprs))
+    }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprSliceBuilder<F>
+    where F: Invoke<P<ast::Expr>>
+{
+    type Result = ExprSliceBuilder<F>;
+
+    fn invoke(mut self, expr: P<ast::Expr>) -> Self {
+        self.exprs.push(expr);
+        self
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprVecBuilder<F> {
+    builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprVecBuilder<F>
+    where F: Invoke<P<ast::Expr>>
+{
+    type Result = F::Result;
+
+    fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+        let qpath = ExprBuilder::new().qpath()
+            .ty().slice().infer()
+            .id("into_vec");
+
+        self.builder.call()
+            .build(qpath)
+            .arg().box_().build(expr)
+            .build()
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprTryBuilder<F> {
+    builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprTryBuilder<F>
+    where F: Invoke<P<ast::Expr>>
+{
+    type Result = F::Result;
+
+    fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+        // ::std::result::Result::Ok(value) => value,
+        let ok_arm = ArmBuilder::new().span(self.builder.span)
+            .pat().ok().id("value")
+            .body().id("value");
+
+        // ::std::result::Result::Err(err) =>
+        //     return ::std::convert::From::from(err),
+        let err_arm = ArmBuilder::new().span(self.builder.span)
+            .pat().err().id("err")
+            .body().return_expr().err().from().id("err");
+
+        // match $expr {
+        //     $ok_arm,
+        //     $err_arm,
+        // }
+        self.builder.match_().build(expr.clone())
+            .with_arm(ok_arm)
+            .with_arm(err_arm)
+            .build()
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprClosureBuilder<F> {
+    builder: ExprBuilder<F>,
+    capture_by: ast::CaptureBy,
+    span: Span,
+}
+
+impl<F> ExprClosureBuilder<F> {
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn by_value(mut self) -> Self {
+        self.capture_by = ast::CaptureBy::Value;
+        self
+    }
+
+    pub fn by_ref(mut self) -> Self {
+        self.capture_by = ast::CaptureBy::Ref;
+        self
+    }
+
+    pub fn fn_decl(self) -> FnDeclBuilder<Self> {
+        FnDeclBuilder::with_callback(self)
+    }
+
+    pub fn build_fn_decl(self, fn_decl: P<ast::FnDecl>) -> ExprClosureExprBuilder<F> {
+        ExprClosureExprBuilder {
+            builder: self.builder,
+            capture_by: self.capture_by,
+            fn_decl: fn_decl,
+            span: self.span,
+        }
+    }
+}
+
+impl<F> Invoke<P<ast::FnDecl>> for ExprClosureBuilder<F> {
+    type Result = ExprClosureExprBuilder<F>;
+
+    fn invoke(self, fn_decl: P<ast::FnDecl>) -> ExprClosureExprBuilder<F> {
+        self.build_fn_decl(fn_decl)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprClosureExprBuilder<F> {
+    builder: ExprBuilder<F>,
+    capture_by: ast::CaptureBy,
+    fn_decl: P<ast::FnDecl>,
+    span: Span,
+}
+
+impl<F> ExprClosureExprBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    pub fn expr(self) -> ExprBuilder<Self> {
+        let span = self.span;
+        ExprBuilder::with_callback(self).span(span)
+    }
+
+    pub fn build_expr(self, expr: P<ast::Expr>) -> F::Result {
+        self.builder.build_expr_kind(ast::ExprKind::Closure(self.capture_by, self.fn_decl, expr, self.span))
+    }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprClosureExprBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+        self.build_expr(expr)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprWhileBuilder<F> {
+    builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprWhileBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = ExprWhileBlockBuilder<F>;
+
+    fn invoke(self, condition: P<ast::Expr>) -> ExprWhileBlockBuilder<F> {
+        ExprWhileBlockBuilder {
+            span: self.builder.span,
+            builder: self.builder,
+            condition: condition,
+            pat: None,
+            label: None,
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprWhileBlockBuilder<F> {
+    builder: ExprBuilder<F>,
+    condition: P<ast::Expr>,
+    pat: Option<P<ast::Pat>>,
+    span: Span,
+    label: Option<ast::SpannedIdent>,
+}
+
+impl<F> ExprWhileBlockBuilder<F> {
+    pub fn pat(self) -> PatBuilder<Self> {
+        PatBuilder::with_callback(self)
+    }
+
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn label<I>(mut self, id: I) -> Self
+        where I: ToIdent,
+    {
+        self.label = Some(respan(self.span, id.to_ident()));
+        self
+    }
+
+    pub fn build_pat(mut self, pat: P<ast::Pat>) -> Self {
+        self.pat = Some(pat);
+        self
+    }
+}
+
+impl<F> ExprWhileBlockBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    pub fn block(self) -> BlockBuilder<Self> {
+        BlockBuilder::with_callback(self)
+    }
+
+    pub fn build_block(self, block: P<ast::Block>) -> F::Result {
+        match self.pat {
+            Some(p) => self.builder.build_expr_kind(ast::ExprKind::WhileLet(
+                p, self.condition, block, self.label)),
+            None => self.builder.build_expr_kind(ast::ExprKind::While(
+                self.condition, block, self.label)),
+        }
+    }
+}
+
+impl<F> Invoke<P<ast::Pat>> for ExprWhileBlockBuilder<F> {
+    type Result = Self;
+
+    fn invoke(self, pat: P<ast::Pat>) -> Self {
+        self.build_pat(pat)
+    }
+}
+
+impl<F> Invoke<P<ast::Block>> for ExprWhileBlockBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, block: P<ast::Block>) -> F::Result {
+        self.build_block(block)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprTypeBuilder<F> {
+    builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprTypeBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = TyBuilder<ExprTypeTyBuilder<F>>;
+
+    fn invoke(self, expr: P<ast::Expr>) -> TyBuilder<ExprTypeTyBuilder<F>> {
+        TyBuilder::with_callback(ExprTypeTyBuilder {
+            builder: self.builder,
+            expr: expr,
+        })
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprTypeTyBuilder<F> {
+    builder: ExprBuilder<F>,
+    expr: P<ast::Expr>,
+}
+
+impl<F> Invoke<P<ast::Ty>> for ExprTypeTyBuilder<F>
+    where F: Invoke<P<ast::Expr>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, ty: P<ast::Ty>) -> F::Result {
+        self.builder.build_expr_kind(ast::ExprKind::Type(self.expr, ty))
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/fn_decl.rs
@@ -0,0 +1,262 @@
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span, respan};
+use syntax::ptr::P;
+
+use ident::ToIdent;
+use invoke::{Invoke, Identity};
+use pat::PatBuilder;
+use self_::SelfBuilder;
+use ty::TyBuilder;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct FnDeclBuilder<F=Identity> {
+    callback: F,
+    span: Span,
+    args: Vec<ast::Arg>,
+    variadic: bool,
+}
+
+impl FnDeclBuilder {
+    pub fn new() -> FnDeclBuilder {
+        FnDeclBuilder::with_callback(Identity)
+    }
+}
+
+impl<F> FnDeclBuilder<F>
+    where F: Invoke<P<ast::FnDecl>>,
+{
+    pub fn with_callback(callback: F) -> Self {
+        FnDeclBuilder {
+            callback: callback,
+            span: DUMMY_SP,
+            args: Vec::new(),
+            variadic: false,
+        }
+    }
+
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn variadic(mut self) -> Self {
+        self.variadic = true;
+        self
+    }
+
+    pub fn with_self(self, explicit_self: ast::ExplicitSelf) -> Self {
+        let self_ident = respan(self.span, "self".to_ident());
+        self.with_arg(ast::Arg::from_self(explicit_self, self_ident))
+    }
+
+    pub fn self_(self) -> SelfBuilder<Self> {
+        SelfBuilder::with_callback(self)
+    }
+
+    pub fn with_arg(mut self, arg: ast::Arg) -> Self {
+        self.args.push(arg);
+        self
+    }
+
+    pub fn with_args<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=ast::Arg>
+    {
+        self.args.extend(iter);
+        self
+    }
+
+    pub fn arg(self) -> ArgBuilder<Self> {
+        ArgBuilder::with_callback(self)
+    }
+
+    pub fn arg_id<T>(self, id: T) -> ArgPatBuilder<Self>
+        where T: ToIdent,
+    {
+        self.arg().pat().id(id)
+    }
+
+    pub fn arg_ref_id<T>(self, id: T) -> ArgPatBuilder<Self>
+        where T: ToIdent,
+    {
+        self.arg().ref_id(id)
+    }
+
+    pub fn arg_mut_id<T>(self, id: T) -> ArgPatBuilder<Self>
+        where T: ToIdent,
+    {
+        self.arg().mut_id(id)
+    }
+
+    pub fn arg_ref_mut_id<T>(self, id: T) -> ArgPatBuilder<Self>
+        where T: ToIdent,
+    {
+        self.arg().ref_mut_id(id)
+    }
+
+    pub fn no_return(self) -> F::Result {
+        self.return_().never()
+    }
+
+    pub fn default_return(self) -> F::Result {
+        let ret_ty = ast::FunctionRetTy::Default(self.span);
+        self.build(ret_ty)
+    }
+
+    pub fn build_return(self, ty: P<ast::Ty>) -> F::Result {
+        self.build(ast::FunctionRetTy::Ty(ty))
+    }
+
+    pub fn return_(self) -> TyBuilder<Self> {
+        let span = self.span;
+        TyBuilder::with_callback(self).span(span)
+    }
+
+    pub fn build(self, output: ast::FunctionRetTy) -> F::Result {
+        self.callback.invoke(P(ast::FnDecl {
+            inputs: self.args,
+            output: output,
+            variadic: self.variadic,
+        }))
+    }
+}
+
+impl<F> Invoke<ast::Arg> for FnDeclBuilder<F>
+    where F: Invoke<P<ast::FnDecl>>
+{
+    type Result = Self;
+
+    fn invoke(self, arg: ast::Arg) -> Self {
+        self.with_arg(arg)
+    }
+}
+
+impl<F> Invoke<P<ast::Ty>> for FnDeclBuilder<F>
+    where F: Invoke<P<ast::FnDecl>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, ty: P<ast::Ty>) -> F::Result {
+        self.build_return(ty)
+    }
+}
+
+impl<F> Invoke<ast::ExplicitSelf> for FnDeclBuilder<F>
+    where F: Invoke<P<ast::FnDecl>>,
+{
+    type Result = Self;
+
+    fn invoke(self, explicit_self: ast::ExplicitSelf) -> Self {
+        self.with_self(explicit_self)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ArgBuilder<F=Identity> {
+    callback: F,
+    span: Span,
+}
+
+impl ArgBuilder {
+    pub fn new() -> Self {
+        ArgBuilder::with_callback( Identity)
+    }
+}
+
+impl<F> ArgBuilder<F>
+    where F: Invoke<ast::Arg>,
+{
+    pub fn with_callback(callback: F) -> ArgBuilder<F> {
+        ArgBuilder {
+            callback: callback,
+            span: DUMMY_SP,
+        }
+    }
+
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn with_pat(self, pat: P<ast::Pat>) -> ArgPatBuilder<F> {
+        ArgPatBuilder {
+            callback: self.callback,
+            span: self.span,
+            pat: pat,
+        }
+    }
+
+    pub fn pat(self) -> PatBuilder<Self> {
+        PatBuilder::with_callback(self)
+    }
+
+    pub fn id<T>(self, id: T) -> ArgPatBuilder<F>
+        where T: ToIdent,
+    {
+        self.pat().id(id)
+    }
+
+    pub fn ref_id<T>(self, id: T) -> ArgPatBuilder<F>
+        where T: ToIdent,
+    {
+        self.pat().ref_id(id)
+    }
+
+    pub fn mut_id<T>(self, id: T) -> ArgPatBuilder<F>
+        where T: ToIdent,
+    {
+        self.pat().mut_id(id)
+    }
+
+    pub fn ref_mut_id<T>(self, id: T) -> ArgPatBuilder<F>
+        where T: ToIdent,
+    {
+        self.pat().ref_mut_id(id)
+    }
+}
+
+impl<F> Invoke<P<ast::Pat>> for ArgBuilder<F>
+    where F: Invoke<ast::Arg>
+{
+    type Result = ArgPatBuilder<F>;
+
+    fn invoke(self, pat: P<ast::Pat>) -> Self::Result {
+        self.with_pat(pat)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ArgPatBuilder<F> {
+    callback: F,
+    span: Span,
+    pat: P<ast::Pat>,
+}
+
+impl<F> ArgPatBuilder<F>
+    where F: Invoke<ast::Arg>
+{
+    pub fn with_ty(self, ty: P<ast::Ty>) -> F::Result {
+        self.callback.invoke(ast::Arg {
+            id: ast::DUMMY_NODE_ID,
+            ty: ty,
+            pat: self.pat,
+        })
+    }
+
+    pub fn ty(self) -> TyBuilder<Self> {
+        let span = self.span;
+        TyBuilder::with_callback(self).span(span)
+    }
+}
+
+impl<F> Invoke<P<ast::Ty>> for ArgPatBuilder<F>
+    where F: Invoke<ast::Arg>
+{
+    type Result = F::Result;
+
+    fn invoke(self, ty: P<ast::Ty>) -> F::Result {
+        self.with_ty(ty)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/generics.rs
@@ -0,0 +1,254 @@
+use std::iter::IntoIterator;
+
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span};
+use syntax::ptr::P;
+
+use ident::ToIdent;
+use invoke::{Invoke, Identity};
+use lifetime::{IntoLifetime, IntoLifetimeDef, LifetimeDefBuilder};
+use name::ToName;
+use path::IntoPath;
+use ty_param::TyParamBuilder;
+use where_predicate::WherePredicateBuilder;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct GenericsBuilder<F=Identity> {
+    callback: F,
+    span: Span,
+    lifetimes: Vec<ast::LifetimeDef>,
+    ty_params: Vec<ast::TyParam>,
+    predicates: Vec<ast::WherePredicate>,
+}
+
+impl GenericsBuilder {
+    pub fn new() -> Self {
+        GenericsBuilder::with_callback(Identity)
+    }
+
+    pub fn from_generics(generics: ast::Generics) -> Self {
+        GenericsBuilder::from_generics_with_callback(generics, Identity)
+    }
+}
+
+impl<F> GenericsBuilder<F>
+    where F: Invoke<ast::Generics>,
+{
+    pub fn with_callback(callback: F) -> Self {
+        GenericsBuilder {
+            callback: callback,
+            span: DUMMY_SP,
+            lifetimes: Vec::new(),
+            ty_params: Vec::new(),
+            predicates: Vec::new(),
+        }
+    }
+
+    pub fn from_generics_with_callback(generics: ast::Generics, callback: F) -> Self {
+        GenericsBuilder {
+            callback: callback,
+            span: DUMMY_SP,
+            lifetimes: generics.lifetimes,
+            ty_params: generics.ty_params.into_vec(),
+            predicates: generics.where_clause.predicates,
+        }
+    }
+
+    pub fn with(self, generics: ast::Generics) -> Self {
+        self.with_lifetimes(generics.lifetimes.into_iter())
+            .with_ty_params(generics.ty_params.into_iter())
+            .with_predicates(generics.where_clause.predicates.into_iter())
+    }
+
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn with_lifetimes<I, L>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=L>,
+              L: IntoLifetimeDef,
+    {
+        let iter = iter.into_iter().map(|lifetime_def| lifetime_def.into_lifetime_def());
+        self.lifetimes.extend(iter);
+        self
+    }
+
+    pub fn with_lifetime_names<I, N>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=N>,
+              N: ToName,
+    {
+        for name in iter {
+            self = self.lifetime_name(name);
+        }
+        self
+    }
+
+    pub fn with_lifetime(mut self, lifetime: ast::LifetimeDef) -> Self {
+        self.lifetimes.push(lifetime);
+        self
+    }
+
+    pub fn lifetime_name<N>(self, name: N) -> Self
+        where N: ToName,
+    {
+        self.lifetime(name).build()
+    }
+
+    pub fn lifetime<N>(self, name: N) -> LifetimeDefBuilder<Self>
+        where N: ToName,
+    {
+        LifetimeDefBuilder::with_callback(name, self)
+    }
+
+    pub fn with_ty_params<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=ast::TyParam>,
+    {
+        self.ty_params.extend(iter);
+        self
+    }
+
+    pub fn with_ty_param_ids<I, T>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=T>,
+              T: ToIdent,
+    {
+        for id in iter {
+            self = self.ty_param_id(id);
+        }
+        self
+    }
+
+    pub fn with_ty_param(mut self, ty_param: ast::TyParam) -> Self {
+        self.ty_params.push(ty_param);
+        self
+    }
+
+    pub fn ty_param_id<I>(self, id: I) -> Self
+        where I: ToIdent,
+    {
+        self.ty_param(id).build()
+    }
+
+    pub fn ty_param<I>(self, id: I) -> TyParamBuilder<Self>
+        where I: ToIdent,
+    {
+        let span = self.span;
+        TyParamBuilder::with_callback(id, self).span(span)
+    }
+
+    pub fn with_predicates<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=ast::WherePredicate>,
+    {
+        self.predicates.extend(iter);
+        self
+    }
+
+    pub fn with_predicate(mut self, predicate: ast::WherePredicate) -> Self {
+        self.predicates.push(predicate);
+        self
+    }
+
+    pub fn predicate(self) -> WherePredicateBuilder<Self> {
+        WherePredicateBuilder::with_callback(self)
+    }
+
+    pub fn add_lifetime_bound<L>(mut self, lifetime: L) -> Self
+        where L: IntoLifetime,
+    {
+        let lifetime = lifetime.into_lifetime();
+
+        for lifetime_def in &mut self.lifetimes {
+            lifetime_def.bounds.push(lifetime);
+        }
+
+        for ty_param in &mut self.ty_params {
+            *ty_param = TyParamBuilder::from_ty_param(ty_param.clone())
+                .lifetime_bound(lifetime)
+                .build();
+        }
+
+        self 
+    }
+
+    pub fn add_ty_param_bound<P>(mut self, path: P) -> Self
+        where P: IntoPath,
+    {
+        let path = path.into_path();
+
+        for ty_param in &mut self.ty_params {
+            *ty_param = TyParamBuilder::from_ty_param(ty_param.clone())
+                .trait_bound(path.clone()).build()
+                .build();
+        }
+
+        self 
+    }
+
+    pub fn strip_bounds(self) -> Self {
+        self.strip_lifetimes()
+            .strip_ty_params()
+            .strip_predicates()
+    }
+
+    pub fn strip_lifetimes(mut self) -> Self {
+        for lifetime in &mut self.lifetimes {
+            lifetime.bounds = vec![];
+        }
+        self
+    }
+
+    pub fn strip_ty_params(mut self) -> Self {
+        for ty_param in &mut self.ty_params {
+            ty_param.bounds = P::new();
+        }
+        self
+    }
+
+    pub fn strip_predicates(mut self) -> Self {
+        self.predicates = vec![];
+        self
+    }
+
+    pub fn build(self) -> F::Result {
+        self.callback.invoke(ast::Generics {
+            lifetimes: self.lifetimes,
+            ty_params: P::from_vec(self.ty_params),
+            where_clause: ast::WhereClause {
+                id: ast::DUMMY_NODE_ID,
+                predicates: self.predicates,
+            },
+            span: self.span,
+        })
+    }
+}
+
+impl<F> Invoke<ast::LifetimeDef> for GenericsBuilder<F>
+    where F: Invoke<ast::Generics>,
+{
+    type Result = Self;
+
+    fn invoke(self, lifetime: ast::LifetimeDef) -> Self {
+        self.with_lifetime(lifetime)
+    }
+}
+
+impl<F> Invoke<ast::TyParam> for GenericsBuilder<F>
+    where F: Invoke<ast::Generics>,
+{
+    type Result = Self;
+
+    fn invoke(self, ty_param: ast::TyParam) -> Self {
+        self.with_ty_param(ty_param)
+    }
+}
+
+impl<F> Invoke<ast::WherePredicate> for GenericsBuilder<F>
+    where F: Invoke<ast::Generics>,
+{
+    type Result = Self;
+
+    fn invoke(self, predicate: ast::WherePredicate) -> Self {
+        self.with_predicate(predicate)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/ident.rs
@@ -0,0 +1,45 @@
+use syntax::ast;
+
+use name::ToName;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub trait ToIdent {
+    fn to_ident(&self) -> ast::Ident;
+}
+
+impl ToIdent for ast::Ident {
+    fn to_ident(&self) -> ast::Ident {
+        *self
+    }
+}
+
+impl ToIdent for ast::Name {
+    fn to_ident(&self) -> ast::Ident {
+        ast::Ident::with_empty_ctxt(*self)
+    }
+}
+
+impl<'a> ToIdent for &'a str {
+    fn to_ident(&self) -> ast::Ident {
+        self.to_name().to_ident()
+    }
+}
+
+impl ToIdent for String {
+    fn to_ident(&self) -> ast::Ident {
+        (&**self).to_ident()
+    }
+}
+
+impl<'a, T> ToIdent for &'a T where T: ToIdent {
+    fn to_ident(&self) -> ast::Ident {
+        (**self).to_ident()
+    }
+}
+
+impl<'a, T> ToIdent for &'a mut T where T: ToIdent {
+    fn to_ident(&self) -> ast::Ident {
+        (**self).to_ident()
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/invoke.rs
@@ -0,0 +1,16 @@
+pub trait Invoke<A> {
+    type Result;
+
+    fn invoke(self, arg: A) -> Self::Result;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+#[derive(Copy, Clone)]
+pub struct Identity;
+
+impl<A> Invoke<A> for Identity {
+    type Result = A;
+
+    fn invoke(self, arg: A) -> A { arg }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/item.rs
@@ -0,0 +1,1490 @@
+#![cfg_attr(feature = "unstable", allow(wrong_self_convention))]
+
+use std::iter::IntoIterator;
+
+use syntax::abi::Abi;
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span, respan};
+use syntax::parse::token::keywords;
+use syntax::ptr::P;
+
+use attr::AttrBuilder;
+use block::BlockBuilder;
+use constant::{Const, ConstBuilder};
+use fn_decl::FnDeclBuilder;
+use generics::GenericsBuilder;
+use ident::ToIdent;
+use invoke::{Invoke, Identity};
+use mac::MacBuilder;
+use method::MethodSigBuilder;
+use path::PathBuilder;
+use struct_field::StructFieldBuilder;
+use ty::TyBuilder;
+use ty_param::TyParamBoundBuilder;
+use variant::VariantBuilder;
+use variant_data::{
+    VariantDataBuilder,
+    VariantDataStructBuilder,
+    VariantDataTupleBuilder,
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemBuilder<F=Identity> {
+    callback: F,
+    span: Span,
+    attrs: Vec<ast::Attribute>,
+    vis: ast::Visibility,
+}
+
+impl ItemBuilder {
+    pub fn new() -> Self {
+        ItemBuilder::with_callback(Identity)
+    }
+}
+
+impl<F> ItemBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    pub fn with_callback(callback: F) -> Self {
+        ItemBuilder {
+            callback: callback,
+            span: DUMMY_SP,
+            attrs: vec![],
+            vis: ast::Visibility::Inherited,
+        }
+    }
+
+    pub fn build(self, item: P<ast::Item>) -> F::Result {
+        self.callback.invoke(item)
+    }
+
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn with_attrs<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=ast::Attribute>,
+    {
+        self.attrs.extend(iter);
+        self
+    }
+
+    pub fn with_attr(mut self, attr: ast::Attribute) -> Self {
+        self.attrs.push(attr);
+        self
+    }
+
+    pub fn attr(self) -> AttrBuilder<Self> {
+        AttrBuilder::with_callback(self)
+    }
+
+    pub fn pub_(mut self) -> Self {
+        self.vis = ast::Visibility::Public;
+        self
+    }
+
+    pub fn build_item_kind<T>(self, id: T, item_kind: ast::ItemKind) -> F::Result
+        where T: ToIdent,
+    {
+        let item = ast::Item {
+            ident: id.to_ident(),
+            attrs: self.attrs,
+            id: ast::DUMMY_NODE_ID,
+            node: item_kind,
+            vis: self.vis,
+            span: self.span,
+        };
+        self.callback.invoke(P(item))
+    }
+
+    pub fn fn_<T>(self, id: T) -> FnDeclBuilder<ItemFnDeclBuilder<F>>
+        where T: ToIdent,
+    {
+        let id = id.to_ident();
+        let span = self.span;
+        FnDeclBuilder::with_callback(ItemFnDeclBuilder {
+            builder: self,
+            span: span,
+            id: id,
+        })
+    }
+
+    pub fn build_use(self, view_path: ast::ViewPath_) -> F::Result {
+        let item = ast::ItemKind::Use(P(respan(self.span, view_path)));
+        self.build_item_kind(keywords::Invalid.ident(), item)
+    }
+
+    pub fn use_(self) -> PathBuilder<ItemUseBuilder<F>> {
+        PathBuilder::with_callback(ItemUseBuilder {
+            builder: self,
+        })
+    }
+
+    pub fn struct_<T>(self, id: T) -> ItemStructBuilder<F>
+        where T: ToIdent,
+    {
+        let id = id.to_ident();
+        let generics = GenericsBuilder::new().build();
+
+        ItemStructBuilder {
+            is_union: false,
+            builder: self,
+            id: id,
+            generics: generics,
+        }
+    }
+
+    pub fn union_<T>(self, id: T) -> ItemStructBuilder<F>
+        where T: ToIdent,
+    {
+        let id = id.to_ident();
+        let generics = GenericsBuilder::new().build();
+
+        ItemStructBuilder {
+            is_union: true,
+            builder: self,
+            id: id,
+            generics: generics,
+        }
+    }
+
+    pub fn unit_struct<T>(self, id: T) -> F::Result
+        where T: ToIdent,
+    {
+        let id = id.to_ident();
+        let data = VariantDataBuilder::new().unit();
+        let generics = GenericsBuilder::new().build();
+
+        let struct_ = ast::ItemKind::Struct(data, generics);
+        self.build_item_kind(id, struct_)
+    }
+
+    pub fn tuple_struct<T>(self, id: T) -> ItemTupleStructBuilder<F>
+        where T: ToIdent,
+    {
+        let id = id.to_ident();
+        let generics = GenericsBuilder::new().build();
+
+        ItemTupleStructBuilder {
+            builder: self,
+            id: id,
+            generics: generics,
+            fields: vec![],
+        }
+    }
+
+    pub fn enum_<T>(self, id: T) -> ItemEnumBuilder<F>
+        where T: ToIdent,
+    {
+        let id = id.to_ident();
+        let span = self.span;
+        let generics = GenericsBuilder::new().span(span).build();
+
+        ItemEnumBuilder {
+            builder: self,
+            id: id,
+            generics: generics,
+            variants: vec![],
+        }
+    }
+
+    pub fn extern_crate<T>(self, id: T) -> ItemExternCrateBuilder<F>
+        where T: ToIdent,
+    {
+        let id = id.to_ident();
+
+        ItemExternCrateBuilder {
+            builder: self,
+            id: id,
+        }
+    }
+
+    pub fn mac(self) -> MacBuilder<ItemMacBuilder<F>> {
+        self.mac_id(keywords::Invalid.ident())
+    }
+
+    pub fn mac_id<T>(self, id: T) -> MacBuilder<ItemMacBuilder<F>>
+        where T: ToIdent,
+    {
+        let span = self.span;
+        MacBuilder::with_callback(ItemMacBuilder {
+            builder: self,
+            id: id.to_ident(),
+        }).span(span)
+    }
+
+    pub fn type_<T>(self, id: T) -> ItemTyBuilder<F>
+        where T: ToIdent,
+    {
+        let id = id.to_ident();
+        let generics = GenericsBuilder::new().build();
+
+        ItemTyBuilder {
+            builder: self,
+            id: id,
+            generics: generics,
+        }
+    }
+
+    pub fn trait_<T>(self, id: T) -> ItemTraitBuilder<F>
+        where T: ToIdent,
+    {
+        ItemTraitBuilder {
+            builder: self,
+            id: id.to_ident(),
+            unsafety: ast::Unsafety::Normal,
+            generics: GenericsBuilder::new().build(),
+            bounds: vec![],
+            items: vec![],
+        }
+    }
+
+    pub fn impl_(self) -> ItemImplBuilder<F> {
+        let generics = GenericsBuilder::new().build();
+
+        ItemImplBuilder {
+            builder: self,
+            unsafety: ast::Unsafety::Normal,
+            polarity: ast::ImplPolarity::Positive,
+            generics: generics,
+            trait_ref: None,
+            items: vec![],
+        }
+    }
+
+    pub fn const_<T>(self, id: T) -> ConstBuilder<ItemConstBuilder<F>>
+        where T: ToIdent,
+    {
+        ConstBuilder::with_callback(ItemConstBuilder {
+            builder: self,
+            id: id.to_ident(),
+        })
+    }
+}
+
+impl<F> Invoke<ast::Attribute> for ItemBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = Self;
+
+    fn invoke(self, attr: ast::Attribute) -> Self {
+        self.with_attr(attr)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemFnDeclBuilder<F> {
+    builder: ItemBuilder<F>,
+    span: Span,
+    id: ast::Ident,
+}
+
+impl<F> Invoke<P<ast::FnDecl>> for ItemFnDeclBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = ItemFnBuilder<F>;
+
+    fn invoke(self, fn_decl: P<ast::FnDecl>) -> ItemFnBuilder<F> {
+        let generics = GenericsBuilder::new().build();
+
+        ItemFnBuilder {
+            builder: self.builder,
+            span: self.span,
+            id: self.id,
+            fn_decl: fn_decl,
+            unsafety: ast::Unsafety::Normal,
+            constness: ast::Constness::NotConst,
+            abi: Abi::Rust,
+            generics: generics,
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemFnBuilder<F> {
+    builder: ItemBuilder<F>,
+    span: Span,
+    id: ast::Ident,
+    fn_decl: P<ast::FnDecl>,
+    unsafety: ast::Unsafety,
+    constness: ast::Constness,
+    abi: Abi,
+    generics: ast::Generics,
+}
+
+impl<F> ItemFnBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    pub fn unsafe_(mut self) -> Self {
+        self.unsafety = ast::Unsafety::Unsafe;
+        self
+    }
+
+    pub fn const_(mut self) -> Self {
+        self.constness = ast::Constness::Const;
+        self
+    }
+
+    pub fn abi(mut self, abi: Abi) -> Self {
+        self.abi = abi;
+        self
+    }
+
+    pub fn generics(self) -> GenericsBuilder<Self> {
+        GenericsBuilder::with_callback(self)
+    }
+
+    pub fn build(self, block: P<ast::Block>) -> F::Result {
+        self.builder.build_item_kind(self.id, ast::ItemKind::Fn(
+            self.fn_decl,
+            self.unsafety,
+            respan(self.span, self.constness),
+            self.abi,
+            self.generics,
+            block,
+        ))
+    }
+
+    pub fn block(self) -> BlockBuilder<Self> {
+        BlockBuilder::with_callback(self)
+    }
+}
+
+impl<F> Invoke<ast::Generics> for ItemFnBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = Self;
+
+    fn invoke(mut self, generics: ast::Generics) -> Self {
+        self.generics = generics;
+        self
+    }
+}
+
+impl<F> Invoke<P<ast::Block>> for ItemFnBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, block: P<ast::Block>) -> F::Result {
+        self.build(block)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemUseBuilder<F> {
+    builder: ItemBuilder<F>,
+}
+
+impl<F> Invoke<ast::Path> for ItemUseBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = ItemUsePathBuilder<F>;
+
+    fn invoke(self, path: ast::Path) -> ItemUsePathBuilder<F> {
+        ItemUsePathBuilder {
+            builder: self.builder,
+            path: path,
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemUsePathBuilder<F> {
+    builder: ItemBuilder<F>,
+    path: ast::Path,
+}
+
+impl<F> ItemUsePathBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    pub fn as_<T>(self, id: T) -> F::Result
+        where T: ToIdent,
+    {
+        self.builder.build_use(ast::ViewPathSimple(id.to_ident(), self.path))
+    }
+
+    pub fn build(self) -> F::Result {
+        let id = {
+            let segment = self.path.segments.last().expect("path with no segments!");
+            segment.identifier
+        };
+        self.as_(id)
+    }
+
+    pub fn glob(self) -> F::Result {
+        self.builder.build_use(ast::ViewPathGlob(self.path))
+    }
+
+    pub fn list(self) -> ItemUsePathListBuilder<F> {
+        let span =  self.builder.span;
+        ItemUsePathListBuilder {
+            builder: self.builder,
+            span: span,
+            path: self.path,
+            idents: Vec::new(),
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemUsePathListBuilder<F> {
+    builder: ItemBuilder<F>,
+    span: Span,
+    path: ast::Path,
+    idents: Vec<ast::PathListItem>,
+}
+
+impl<F> ItemUsePathListBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn self_(mut self) -> Self {
+        self.idents.push(respan(self.span, ast::PathListItem_ {
+            name: keywords::SelfValue.ident(),
+            rename: None,
+            id: ast::DUMMY_NODE_ID,
+        }));
+        self
+    }
+
+    pub fn id<T>(mut self, id: T) -> Self
+        where T: ToIdent,
+    {
+        self.idents.push(respan(self.span, ast::PathListItem_ {
+            name: id.to_ident(),
+            rename: None,
+            id: ast::DUMMY_NODE_ID,
+        }));
+        self
+    }
+
+    pub fn build(self) -> F::Result {
+        self.builder.build_use(ast::ViewPathList(self.path, self.idents))
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemStructBuilder<F> {
+    is_union: bool,
+    builder: ItemBuilder<F>,
+    id: ast::Ident,
+    generics: ast::Generics,
+}
+
+impl<F> ItemStructBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    pub fn with_generics(mut self, generics: ast::Generics) -> Self {
+        self.generics = generics;
+        self
+    }
+
+    pub fn generics(self) -> GenericsBuilder<Self> {
+        GenericsBuilder::with_callback(self)
+    }
+
+    pub fn with_fields<I>(self, iter: I) -> VariantDataStructBuilder<Self>
+        where I: IntoIterator<Item=ast::StructField>,
+    {
+        let span = self.builder.span;
+        VariantDataBuilder::with_callback(self).span(span).struct_().with_fields(iter)
+    }
+
+    pub fn with_field(self, field: ast::StructField) -> VariantDataStructBuilder<Self> {
+        let span = self.builder.span;
+        VariantDataBuilder::with_callback(self).span(span).struct_().with_field(field)
+    }
+
+    pub fn field<T>(self, id: T) -> StructFieldBuilder<VariantDataStructBuilder<Self>>
+        where T: ToIdent,
+    {
+        let span = self.builder.span;
+        VariantDataBuilder::with_callback(self).span(span).struct_().field(id)
+    }
+
+    pub fn build(self) -> F::Result {
+        VariantDataBuilder::with_callback(self).struct_().build()
+    }
+}
+
+impl<F> Invoke<ast::Generics> for ItemStructBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = Self;
+
+    fn invoke(self, generics: ast::Generics) -> Self {
+        self.with_generics(generics)
+    }
+}
+
+impl<F> Invoke<ast::VariantData> for ItemStructBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, data: ast::VariantData) -> F::Result {
+        let kind = if self.is_union {
+            ast::ItemKind::Union(data, self.generics)
+        } else {
+            ast::ItemKind::Struct(data, self.generics)
+        };
+
+        self.builder.build_item_kind(self.id, kind)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemTupleStructBuilder<F> {
+    builder: ItemBuilder<F>,
+    id: ast::Ident,
+    generics: ast::Generics,
+    fields: Vec<ast::StructField>,
+}
+
+impl<F> ItemTupleStructBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    pub fn generics(self) -> GenericsBuilder<Self> {
+        GenericsBuilder::with_callback(self)
+    }
+
+    pub fn with_tys<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=P<ast::Ty>>,
+    {
+        for ty in iter {
+            self = self.ty().build(ty);
+        }
+        self
+    }
+
+    pub fn ty(self) -> TyBuilder<Self> {
+        let span = self.builder.span;
+        TyBuilder::with_callback(self).span(span)
+    }
+
+    pub fn field(self) -> StructFieldBuilder<Self> {
+        let span = self.builder.span;
+        StructFieldBuilder::unnamed_with_callback(self).span(span)
+    }
+
+    pub fn build(self) -> F::Result {
+        let data = ast::VariantData::Tuple(self.fields, ast::DUMMY_NODE_ID);
+        let struct_ = ast::ItemKind::Struct(data, self.generics);
+        self.builder.build_item_kind(self.id, struct_)
+    }
+}
+
+impl<F> Invoke<ast::Generics> for ItemTupleStructBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = Self;
+
+    fn invoke(mut self, generics: ast::Generics) -> Self {
+        self.generics = generics;
+        self
+    }
+}
+
+impl<F> Invoke<P<ast::Ty>> for ItemTupleStructBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = Self;
+
+    fn invoke(self, ty: P<ast::Ty>) -> Self {
+        self.field().build_ty(ty)
+    }
+}
+
+impl<F> Invoke<ast::StructField> for ItemTupleStructBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = Self;
+
+    fn invoke(mut self, field: ast::StructField) -> Self {
+        self.fields.push(field);
+        self
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemEnumBuilder<F> {
+    builder: ItemBuilder<F>,
+    id: ast::Ident,
+    generics: ast::Generics,
+    variants: Vec<ast::Variant>,
+}
+
+impl<F> ItemEnumBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    pub fn generics(self) -> GenericsBuilder<Self> {
+        let span = self.builder.span;
+        GenericsBuilder::with_callback(self).span(span)
+    }
+
+    pub fn with_variants<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=ast::Variant>,
+    {
+        self.variants.extend(iter);
+        self
+    }
+
+    pub fn with_variant(mut self, variant: ast::Variant) -> Self {
+        self.variants.push(variant);
+        self
+    }
+
+    pub fn with_variant_(self, variant: ast::Variant_) -> Self {
+        let variant = respan(self.builder.span, variant);
+        self.with_variant(variant)
+    }
+
+    pub fn ids<I, T>(mut self, ids: I) -> Self
+        where I: IntoIterator<Item=T>,
+              T: ToIdent,
+    {
+        for id in ids {
+            self = self.id(id);
+        }
+        self
+    }
+
+    pub fn id<T>(self, id: T) -> Self
+        where T: ToIdent,
+    {
+        self.variant(id).unit()
+    }
+
+    pub fn tuple<T>(self, id: T) -> StructFieldBuilder<VariantDataTupleBuilder<VariantBuilder<Self>>>
+        where T: ToIdent,
+    {
+        self.variant(id).tuple()
+    }
+
+    pub fn struct_<T>(self, id: T) -> VariantDataStructBuilder<VariantBuilder<Self>>
+        where T: ToIdent,
+    {
+        self.variant(id).struct_()
+    }
+
+    pub fn variant<T>(self, id: T) -> VariantBuilder<Self>
+        where T: ToIdent,
+    {
+        let span = self.builder.span;
+        VariantBuilder::with_callback(id, self).span(span)
+    }
+
+    pub fn build(self) -> F::Result {
+        let enum_def = ast::EnumDef {
+            variants: self.variants,
+        };
+        let enum_ = ast::ItemKind::Enum(enum_def, self.generics);
+        self.builder.build_item_kind(self.id, enum_)
+    }
+}
+
+impl<F> Invoke<ast::Generics> for ItemEnumBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = Self;
+
+    fn invoke(mut self, generics: ast::Generics) -> Self {
+        self.generics = generics;
+        self
+    }
+}
+
+impl<F> Invoke<ast::Variant> for ItemEnumBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = Self;
+
+    fn invoke(self, variant: ast::Variant) -> Self {
+        self.with_variant(variant)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// A builder for extern crate items
+pub struct ItemExternCrateBuilder<F> {
+    builder: ItemBuilder<F>,
+    id: ast::Ident,
+}
+
+impl<F> ItemExternCrateBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    pub fn with_name(self, name: ast::Name) -> F::Result {
+        let extern_ = ast::ItemKind::ExternCrate(Some(name));
+        self.builder.build_item_kind(self.id, extern_)
+    }
+
+    pub fn build(self) -> F::Result {
+        let extern_ = ast::ItemKind::ExternCrate(None);
+        self.builder.build_item_kind(self.id, extern_)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// A builder for macro invocation items.
+///
+/// Specifying the macro path returns a `MacBuilder`, which is used to
+/// add expressions to the macro invocation.
+pub struct ItemMacBuilder<F> {
+    builder: ItemBuilder<F>,
+    id: ast::Ident,
+}
+
+impl<F> Invoke<ast::Mac> for ItemMacBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, mac: ast::Mac) -> F::Result {
+        self.builder.build_item_kind(self.id, ast::ItemKind::Mac(mac))
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemTyBuilder<F> {
+    builder: ItemBuilder<F>,
+    id: ast::Ident,
+    generics: ast::Generics,
+}
+
+impl<F> ItemTyBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    pub fn generics(self) -> GenericsBuilder<Self> {
+        GenericsBuilder::with_callback(self)
+    }
+
+    pub fn ty(self) -> TyBuilder<Self> {
+        let span = self.builder.span;
+        TyBuilder::with_callback(self).span(span)
+    }
+
+    pub fn build_ty(self, ty: P<ast::Ty>) -> F::Result {
+        let ty_ = ast::ItemKind::Ty(ty, self.generics);
+        self.builder.build_item_kind(self.id, ty_)
+    }
+}
+
+impl<F> Invoke<ast::Generics> for ItemTyBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = Self;
+
+    fn invoke(mut self, generics: ast::Generics) -> Self {
+        self.generics = generics;
+        self
+    }
+}
+
+impl<F> Invoke<P<ast::Ty>> for ItemTyBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, ty: P<ast::Ty>) -> F::Result {
+        self.build_ty(ty)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemTraitBuilder<F> {
+    builder: ItemBuilder<F>,
+    id: ast::Ident,
+    unsafety: ast::Unsafety,
+    generics: ast::Generics,
+    bounds: Vec<ast::TyParamBound>,
+    items: Vec<ast::TraitItem>,
+}
+
+impl<F> ItemTraitBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    pub fn unsafe_(mut self) -> Self {
+        self.unsafety = ast::Unsafety::Unsafe;
+        self
+    }
+
+    pub fn with_generics(mut self, generics: ast::Generics) -> Self {
+        self.generics = generics;
+        self
+    }
+
+    pub fn generics(self) -> GenericsBuilder<Self> {
+        GenericsBuilder::with_callback(self)
+    }
+
+    pub fn with_bounds<I>(mut self, iter: I) -> Self
+        where I: Iterator<Item=ast::TyParamBound>,
+    {
+        self.bounds.extend(iter);
+        self
+    }
+
+    pub fn with_bound(mut self, bound: ast::TyParamBound) -> Self {
+        self.bounds.push(bound);
+        self
+    }
+
+    pub fn bound(self) -> TyParamBoundBuilder<Self> {
+        TyParamBoundBuilder::with_callback(self)
+    }
+
+    pub fn with_items<I>(mut self, items: I) -> Self
+        where I: IntoIterator<Item=ast::TraitItem>,
+    {
+        self.items.extend(items);
+        self
+    }
+
+    pub fn with_item(mut self, item: ast::TraitItem) -> Self {
+        self.items.push(item);
+        self
+    }
+
+    pub fn item<T>(self, id: T) -> ItemTraitItemBuilder<Self>
+        where T: ToIdent,
+    {
+        ItemTraitItemBuilder::with_callback(id, self)
+    }
+
+    pub fn const_<T>(self, id: T) -> ConstBuilder<ItemTraitItemBuilder<Self>>
+        where T: ToIdent,
+    {
+        self.item(id).const_()
+    }
+
+    pub fn method<T>(self, id: T) -> MethodSigBuilder<ItemTraitItemBuilder<Self>>
+        where T: ToIdent,
+    {
+        self.item(id).method()
+    }
+
+    pub fn type_<T>(self, id: T) -> ItemTraitTypeBuilder<Self>
+        where T: ToIdent,
+    {
+        self.item(id).type_()
+    }
+
+    pub fn build(self) -> F::Result {
+        self.builder.build_item_kind(self.id, ast::ItemKind::Trait(
+            self.unsafety,
+            self.generics,
+            P::from_vec(self.bounds),
+            self.items,
+        ))
+    }
+}
+
+impl<F> Invoke<ast::Generics> for ItemTraitBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = Self;
+
+    fn invoke(self, generics: ast::Generics) -> Self {
+        self.with_generics(generics)
+    }
+}
+
+impl<F> Invoke<ast::TyParamBound> for ItemTraitBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = Self;
+
+    fn invoke(self, bound: ast::TyParamBound) -> Self {
+        self.with_bound(bound)
+    }
+}
+
+impl<F> Invoke<ast::TraitItem> for ItemTraitBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = Self;
+
+    fn invoke(self, item: ast::TraitItem) -> Self {
+        self.with_item(item)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemTraitItemBuilder<F=Identity> {
+    callback: F,
+    id: ast::Ident,
+    attrs: Vec<ast::Attribute>,
+    span: Span,
+}
+
+impl ItemTraitItemBuilder {
+    pub fn new<T>(id: T) -> Self
+        where T: ToIdent,
+    {
+        Self::with_callback(id, Identity)
+    }
+}
+
+impl<F> ItemTraitItemBuilder<F>
+    where F: Invoke<ast::TraitItem>,
+{
+    pub fn with_callback<T>(id: T, callback: F) -> Self
+        where F: Invoke<ast::TraitItem>,
+              T: ToIdent,
+    {
+        ItemTraitItemBuilder {
+            callback: callback,
+            id: id.to_ident(),
+            attrs: vec![],
+            span: DUMMY_SP,
+        }
+    }
+
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn with_attrs<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=ast::Attribute>,
+    {
+        self.attrs.extend(iter);
+        self
+    }
+
+    pub fn with_attr(mut self, attr: ast::Attribute) -> Self {
+        self.attrs.push(attr);
+        self
+    }
+
+    pub fn attr(self) -> AttrBuilder<Self> {
+        AttrBuilder::with_callback(self)
+    }
+
+    pub fn const_(self) -> ConstBuilder<Self> {
+        ConstBuilder::with_callback(self)
+    }
+
+    pub fn method(self) -> MethodSigBuilder<Self> {
+        MethodSigBuilder::with_callback(self)
+    }
+
+    pub fn type_(self) -> ItemTraitTypeBuilder<F> {
+        ItemTraitTypeBuilder {
+            builder: self,
+            bounds: vec![],
+        }
+    }
+
+    pub fn build_item(self, node: ast::TraitItemKind) -> F::Result {
+        let item = ast::TraitItem {
+            id: ast::DUMMY_NODE_ID,
+            ident: self.id,
+            attrs: self.attrs,
+            node: node,
+            span: self.span,
+        };
+        self.callback.invoke(item)
+    }
+}
+
+impl<F> Invoke<ast::Attribute> for ItemTraitItemBuilder<F>
+    where F: Invoke<ast::TraitItem>,
+{
+    type Result = Self;
+
+    fn invoke(self, attr: ast::Attribute) -> Self {
+        self.with_attr(attr)
+    }
+}
+
+impl<F> Invoke<Const> for ItemTraitItemBuilder<F>
+    where F: Invoke<ast::TraitItem>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, const_: Const) -> F::Result {
+        let node = ast::TraitItemKind::Const(
+            const_.ty,
+            const_.expr);
+        self.build_item(node)
+    }
+}
+
+impl<F> Invoke<ast::MethodSig> for ItemTraitItemBuilder<F>
+    where F: Invoke<ast::TraitItem>,
+{
+    type Result = ItemTraitMethodBuilder<F>;
+
+    fn invoke(self, method: ast::MethodSig) -> Self::Result {
+        ItemTraitMethodBuilder {
+            builder: self,
+            method: method,
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemTraitMethodBuilder<F> {
+    builder: ItemTraitItemBuilder<F>,
+    method: ast::MethodSig,
+}
+
+impl<F> ItemTraitMethodBuilder<F>
+    where F: Invoke<ast::TraitItem>,
+{
+    pub fn build_option_block(self, block: Option<P<ast::Block>>) -> F::Result {
+        let node = ast::TraitItemKind::Method(self.method, block);
+        self.builder.build_item(node)
+    }
+
+    pub fn build_block(self, block: P<ast::Block>) -> F::Result {
+        self.build_option_block(Some(block))
+    }
+
+    pub fn build(self) -> F::Result {
+        self.build_option_block(None)
+    }
+}
+
+impl<F> Invoke<P<ast::Block>> for ItemTraitMethodBuilder<F>
+    where F: Invoke<ast::TraitItem>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, block: P<ast::Block>) -> Self::Result {
+        self.build_block(block)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemTraitTypeBuilder<F> {
+    builder: ItemTraitItemBuilder<F>,
+    bounds: Vec<ast::TyParamBound>,
+}
+
+impl<F> ItemTraitTypeBuilder<F>
+    where F: Invoke<ast::TraitItem>,
+{
+    pub fn with_bounds<I>(mut self, iter: I) -> Self
+        where I: Iterator<Item=ast::TyParamBound>,
+    {
+        self.bounds.extend(iter);
+        self
+    }
+
+    pub fn with_bound(mut self, bound: ast::TyParamBound) -> Self {
+        self.bounds.push(bound);
+        self
+    }
+
+    pub fn bound(self) -> TyParamBoundBuilder<Self> {
+        TyParamBoundBuilder::with_callback(self)
+    }
+
+    pub fn build_option_ty(self, ty: Option<P<ast::Ty>>) -> F::Result {
+        let bounds = P::from_vec(self.bounds);
+        let node = ast::TraitItemKind::Type(bounds, ty);
+        self.builder.build_item(node)
+    }
+
+    pub fn build_ty(self, ty: P<ast::Ty>) -> F::Result {
+        self.build_option_ty(Some(ty))
+    }
+
+    pub fn ty(self) -> TyBuilder<Self> {
+        let span = self.builder.span;
+        TyBuilder::with_callback(self).span(span)
+    }
+
+    pub fn build(self) -> F::Result {
+        self.build_option_ty(None)
+    }
+}
+
+impl<F> Invoke<ast::TyParamBound> for ItemTraitTypeBuilder<F>
+    where F: Invoke<ast::TraitItem>,
+{
+    type Result = ItemTraitTypeBuilder<F>;
+
+    fn invoke(self, bound: ast::TyParamBound) -> Self::Result {
+        self.with_bound(bound)
+    }
+}
+
+impl<F> Invoke<P<ast::Ty>> for ItemTraitTypeBuilder<F>
+    where F: Invoke<ast::TraitItem>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, ty: P<ast::Ty>) -> Self::Result {
+        self.build_ty(ty)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemImplBuilder<F> {
+    builder: ItemBuilder<F>,
+    unsafety: ast::Unsafety,
+    polarity: ast::ImplPolarity,
+    generics: ast::Generics,
+    trait_ref: Option<ast::TraitRef>,
+    items: Vec<ast::ImplItem>,
+}
+
+impl<F> ItemImplBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    pub fn unsafe_(mut self) -> Self {
+        self.unsafety = ast::Unsafety::Unsafe;
+        self
+    }
+
+    pub fn negative(mut self) -> Self {
+        self.polarity = ast::ImplPolarity::Negative;
+        self
+    }
+
+    pub fn with_generics(mut self, generics: ast::Generics) -> Self {
+        self.generics = generics;
+        self
+    }
+
+    pub fn generics(self) -> GenericsBuilder<Self> {
+        GenericsBuilder::with_callback(self)
+    }
+
+    pub fn with_trait(mut self, trait_ref: ast::TraitRef) -> Self {
+        self.trait_ref = Some(trait_ref);
+        self
+    }
+
+    pub fn trait_(self) -> PathBuilder<Self> {
+        PathBuilder::with_callback(self)
+    }
+
+    pub fn ty(self) -> TyBuilder<Self> {
+        let span = self.builder.span;
+        TyBuilder::with_callback(self).span(span)
+    }
+
+    pub fn build_ty(self, ty: P<ast::Ty>) -> F::Result {
+        let ty_ = ast::ItemKind::Impl(
+            self.unsafety,
+            self.polarity,
+            self.generics,
+            self.trait_ref,
+            ty,
+            self.items);
+        self.builder.build_item_kind(keywords::Invalid.ident(), ty_)
+    }
+
+    pub fn with_items<I>(mut self, items: I) -> Self
+        where I: IntoIterator<Item=ast::ImplItem>,
+    {
+        self.items.extend(items);
+        self
+    }
+
+    pub fn with_item(mut self, item: ast::ImplItem) -> Self {
+        self.items.push(item);
+        self
+    }
+
+    pub fn item<T>(self, id: T) -> ItemImplItemBuilder<Self>
+        where T: ToIdent,
+    {
+        ItemImplItemBuilder::with_callback(id, self)
+    }
+
+    pub fn const_<T>(self, id: T) -> ConstBuilder<ItemImplItemBuilder<Self>>
+        where T: ToIdent,
+    {
+        self.item(id).const_()
+    }
+
+    pub fn method<T>(self, id: T) -> MethodSigBuilder<ItemImplItemBuilder<Self>>
+        where T: ToIdent,
+    {
+        self.item(id).method()
+    }
+
+    pub fn type_<T>(self, id: T) -> TyBuilder<ItemImplItemBuilder<Self>>
+        where T: ToIdent,
+    {
+        self.item(id).type_()
+    }
+}
+
+impl<F> Invoke<ast::Generics> for ItemImplBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = Self;
+
+    fn invoke(self, generics: ast::Generics) -> Self {
+        self.with_generics(generics)
+    }
+}
+
+impl<F> Invoke<ast::Path> for ItemImplBuilder<F>
+    where F: Invoke<P<ast::Item>>
+{
+    type Result = Self;
+
+    fn invoke(self, path: ast::Path) -> Self {
+        self.with_trait(ast::TraitRef {
+            path: path,
+            ref_id: ast::DUMMY_NODE_ID,
+        })
+    }
+}
+
+impl<F> Invoke<ast::ImplItem> for ItemImplBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = Self;
+
+    fn invoke(self, item: ast::ImplItem) -> Self {
+        self.with_item(item)
+    }
+}
+
+impl<F> Invoke<P<ast::Ty>> for ItemImplBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, ty: P<ast::Ty>) -> F::Result {
+        self.build_ty(ty)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemImplItemBuilder<F=Identity> {
+    callback: F,
+    id: ast::Ident,
+    vis: ast::Visibility,
+    defaultness: ast::Defaultness,
+    attrs: Vec<ast::Attribute>,
+    span: Span,
+}
+
+impl ItemImplItemBuilder {
+    pub fn new<T>(id: T) -> Self
+        where T: ToIdent,
+    {
+        Self::with_callback(id, Identity)
+    }
+}
+
+impl<F> ItemImplItemBuilder<F>
+    where F: Invoke<ast::ImplItem>,
+{
+    pub fn with_callback<T>(id: T, callback: F) -> Self
+        where F: Invoke<ast::ImplItem>,
+              T: ToIdent,
+    {
+        ItemImplItemBuilder {
+            callback: callback,
+            id: id.to_ident(),
+            vis: ast::Visibility::Inherited,
+            defaultness: ast::Defaultness::Final,
+            attrs: vec![],
+            span: DUMMY_SP,
+        }
+    }
+
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn with_attrs<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=ast::Attribute>,
+    {
+        self.attrs.extend(iter);
+        self
+    }
+
+    pub fn with_attr(mut self, attr: ast::Attribute) -> Self {
+        self.attrs.push(attr);
+        self
+    }
+
+    pub fn attr(self) -> AttrBuilder<Self> {
+        AttrBuilder::with_callback(self)
+    }
+
+    pub fn pub_(mut self) -> Self {
+        self.vis = ast::Visibility::Public;
+        self
+    }
+
+    pub fn default(mut self) -> Self {
+        self.defaultness = ast::Defaultness::Default;
+        self
+    }
+
+    pub fn const_(self) -> ConstBuilder<Self> {
+        ConstBuilder::with_callback(self)
+    }
+
+    pub fn build_method(self, method: ast::MethodSig) -> ItemImplMethodBuilder<F> {
+        ItemImplMethodBuilder {
+            builder: self,
+            method: method,
+        }
+    }
+
+    pub fn method(self) -> MethodSigBuilder<Self> {
+        MethodSigBuilder::with_callback(self)
+    }
+
+    pub fn type_(self) -> TyBuilder<Self> {
+        let span = self.span;
+        TyBuilder::with_callback(self).span(span)
+    }
+
+    pub fn mac(self) -> MacBuilder<Self> {
+        MacBuilder::with_callback(self)
+    }
+
+    pub fn build_item(self, node: ast::ImplItemKind) -> F::Result {
+        let item = ast::ImplItem {
+            id: ast::DUMMY_NODE_ID,
+            ident: self.id,
+            vis: self.vis,
+            defaultness: self.defaultness,
+            attrs: self.attrs,
+            node: node,
+            span: self.span,
+        };
+        self.callback.invoke(item)
+    }
+}
+
+impl<F> Invoke<ast::Attribute> for ItemImplItemBuilder<F>
+    where F: Invoke<ast::ImplItem>,
+{
+    type Result = Self;
+
+    fn invoke(self, attr: ast::Attribute) -> Self {
+        self.with_attr(attr)
+    }
+}
+
+impl<F> Invoke<Const> for ItemImplItemBuilder<F>
+    where F: Invoke<ast::ImplItem>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, const_: Const) -> F::Result {
+        let node = ast::ImplItemKind::Const(const_.ty, const_.expr.expect("an expr is required for a const impl item"));
+        self.build_item(node)
+    }
+}
+
+impl<F> Invoke<ast::MethodSig> for ItemImplItemBuilder<F>
+    where F: Invoke<ast::ImplItem>,
+{
+    type Result = ItemImplMethodBuilder<F>;
+
+    fn invoke(self, method: ast::MethodSig) -> Self::Result {
+        self.build_method(method)
+    }
+}
+
+impl<F> Invoke<P<ast::Ty>> for ItemImplItemBuilder<F>
+    where F: Invoke<ast::ImplItem>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, ty: P<ast::Ty>) -> F::Result {
+        let node = ast::ImplItemKind::Type(ty);
+        self.build_item(node)
+    }
+}
+
+impl<F> Invoke<ast::Mac> for ItemImplItemBuilder<F>
+    where F: Invoke<ast::ImplItem>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, mac: ast::Mac) -> F::Result {
+        let node = ast::ImplItemKind::Macro(mac);
+        self.build_item(node)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemImplMethodBuilder<F> {
+    builder: ItemImplItemBuilder<F>,
+    method: ast::MethodSig,
+}
+
+impl<F> ItemImplMethodBuilder<F>
+    where F: Invoke<ast::ImplItem>,
+{
+    pub fn build_block(self, block: P<ast::Block>) -> F::Result {
+        let node = ast::ImplItemKind::Method(self.method, block);
+        self.builder.build_item(node)
+    }
+
+    pub fn block(self) -> BlockBuilder<Self> {
+        BlockBuilder::with_callback(self)
+    }
+}
+
+impl<F> Invoke<P<ast::Block>> for ItemImplMethodBuilder<F>
+    where F: Invoke<ast::ImplItem>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, block: P<ast::Block>) -> Self::Result {
+        self.build_block(block)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemConstBuilder<F> {
+    builder: ItemBuilder<F>,
+    id: ast::Ident,
+}
+
+impl<F> Invoke<Const> for ItemConstBuilder<F>
+    where F: Invoke<P<ast::Item>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, const_: Const) -> F::Result {
+        let ty = ast::ItemKind::Const(const_.ty, const_.expr.expect("an expr is required for a const item"));
+        self.builder.build_item_kind(self.id, ty)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/lib.rs
@@ -0,0 +1,224 @@
+#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private))]
+#![cfg_attr(feature = "unstable-testing", feature(plugin))]
+#![cfg_attr(feature = "unstable-testing", plugin(clippy))]
+#![cfg_attr(feature = "unstable-testing", allow(wrong_self_convention))]
+
+#[cfg(feature = "with-syntex")]
+extern crate syntex_syntax as syntax;
+
+#[cfg(not(feature = "with-syntex"))]
+extern crate syntax;
+
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span};
+use syntax::parse::token;
+
+pub mod arm;
+pub mod attr;
+pub mod block;
+pub mod constant;
+pub mod expr;
+pub mod fn_decl;
+pub mod generics;
+pub mod ident;
+pub mod invoke;
+pub mod item;
+pub mod lifetime;
+pub mod lit;
+pub mod mac;
+pub mod method;
+pub mod name;
+pub mod pat;
+pub mod path;
+pub mod qpath;
+pub mod self_;
+pub mod stmt;
+pub mod str;
+pub mod struct_field;
+pub mod ty;
+pub mod ty_param;
+pub mod variant;
+pub mod variant_data;
+pub mod where_predicate;
+
+//////////////////////////////////////////////////////////////////////////////
+
+#[derive(Copy, Clone)]
+pub struct AstBuilder {
+    span: Span,
+}
+
+impl AstBuilder {
+    pub fn new() -> AstBuilder {
+        AstBuilder {
+            span: DUMMY_SP,
+        }
+    }
+
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn interned_string<S>(&self, s: S) -> token::InternedString
+        where S: str::ToInternedString
+    {
+        s.to_interned_string()
+    }
+
+    pub fn id<I>(&self, id: I) -> ast::Ident
+        where I: ident::ToIdent
+    {
+        id.to_ident()
+    }
+
+    pub fn name<N>(&self, name: N) -> ast::Name
+        where N: name::ToName
+    {
+        name.to_name()
+    }
+
+    pub fn lifetime<L>(&self, lifetime: L) -> ast::Lifetime
+        where L: lifetime::IntoLifetime
+    {
+        lifetime.into_lifetime()
+    }
+
+    pub fn arm(&self) -> arm::ArmBuilder {
+        arm::ArmBuilder::new().span(self.span)
+    }
+
+    pub fn attr(&self) -> attr::AttrBuilder {
+        attr::AttrBuilder::new().span(self.span)
+    }
+
+    pub fn mac(&self) -> mac::MacBuilder {
+        mac::MacBuilder::new().span(self.span)
+    }
+
+    pub fn path(&self) -> path::PathBuilder {
+        path::PathBuilder::new().span(self.span)
+    }
+
+    pub fn qpath(&self) -> qpath::QPathBuilder {
+        qpath::QPathBuilder::new().span(self.span)
+    }
+
+    pub fn ty(&self) -> ty::TyBuilder {
+        ty::TyBuilder::new().span(self.span)
+    }
+
+    pub fn lifetime_def<N>(&self, name: N) -> lifetime::LifetimeDefBuilder
+        where N: name::ToName,
+    {
+        lifetime::LifetimeDefBuilder::new(name)
+    }
+
+    pub fn ty_param<I>(&self, id: I) -> ty_param::TyParamBuilder
+        where I: ident::ToIdent,
+    {
+        ty_param::TyParamBuilder::new(id).span(self.span)
+    }
+
+    pub fn ty_param_bound(&self) -> ty_param::TyParamBoundBuilder {
+        ty_param::TyParamBoundBuilder::new().span(self.span)
+    }
+
+    pub fn from_ty_param(&self, ty_param: ast::TyParam) -> ty_param::TyParamBuilder {
+        ty_param::TyParamBuilder::from_ty_param(ty_param)
+    }
+
+    pub fn generics(&self) -> generics::GenericsBuilder {
+        generics::GenericsBuilder::new().span(self.span)
+    }
+
+    pub fn where_predicate(&self) -> where_predicate::WherePredicateBuilder {
+        where_predicate::WherePredicateBuilder::new().span(self.span)
+    }
+
+    pub fn from_generics(&self, generics: ast::Generics) -> generics::GenericsBuilder {
+        generics::GenericsBuilder::from_generics(generics).span(self.span)
+    }
+
+    pub fn lit(&self) -> lit::LitBuilder {
+        lit::LitBuilder::new().span(self.span)
+    }
+
+    pub fn expr(&self) -> expr::ExprBuilder {
+        expr::ExprBuilder::new().span(self.span)
+    }
+
+    pub fn stmt(&self) -> stmt::StmtBuilder {
+        stmt::StmtBuilder::new().span(self.span)
+    }
+
+    pub fn block(&self) -> block::BlockBuilder {
+        block::BlockBuilder::new().span(self.span)
+    }
+
+    pub fn pat(&self) -> pat::PatBuilder {
+        pat::PatBuilder::new().span(self.span)
+    }
+
+    pub fn fn_decl(&self) -> fn_decl::FnDeclBuilder {
+        fn_decl::FnDeclBuilder::new().span(self.span)
+    }
+
+    pub fn method_sig(&self) -> method::MethodSigBuilder {
+        method::MethodSigBuilder::new().span(self.span)
+    }
+
+    pub fn self_(&self) -> self_::SelfBuilder {
+        self_::SelfBuilder::new().span(self.span)
+    }
+
+    pub fn arg(&self) -> fn_decl::ArgBuilder {
+        fn_decl::ArgBuilder::new().span(self.span)
+    }
+
+    pub fn variant_data(&self) -> variant_data::VariantDataBuilder {
+        variant_data::VariantDataBuilder::new().span(self.span)
+    }
+
+    pub fn variant<T>(&self, id: T) -> variant::VariantBuilder
+        where T: ident::ToIdent,
+    {
+        variant::VariantBuilder::new(id).span(self.span)
+    }
+
+    pub fn struct_field<T>(&self, id: T) -> struct_field::StructFieldBuilder
+        where T: ident::ToIdent,
+    {
+        struct_field::StructFieldBuilder::named(id).span(self.span)
+    }
+
+    pub fn tuple_field(&self) -> struct_field::StructFieldBuilder {
+        struct_field::StructFieldBuilder::unnamed().span(self.span)
+    }
+
+    pub fn item(&self) -> item::ItemBuilder {
+        item::ItemBuilder::new().span(self.span)
+    }
+
+    pub fn trait_item<T>(&self, id: T) -> item::ItemTraitItemBuilder
+        where T: ident::ToIdent,
+    {
+        item::ItemTraitItemBuilder::new(id).span(self.span)
+    }
+
+    pub fn impl_item<T>(&self, id: T) -> item::ItemImplItemBuilder
+        where T: ident::ToIdent,
+    {
+        item::ItemImplItemBuilder::new(id).span(self.span)
+    }
+
+    pub fn const_(&self) -> constant::ConstBuilder {
+        constant::ConstBuilder::new().span(self.span)
+    }
+}
+
+impl Default for AstBuilder {
+    fn default() -> Self {
+        AstBuilder::new()
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/lifetime.rs
@@ -0,0 +1,118 @@
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP};
+
+use invoke::{Invoke, Identity};
+use name::ToName;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub trait IntoLifetime {
+    fn into_lifetime(self) -> ast::Lifetime;
+}
+
+impl IntoLifetime for ast::Lifetime {
+    fn into_lifetime(self) -> ast::Lifetime {
+        self
+    }
+}
+
+impl<'a> IntoLifetime for &'a str {
+    fn into_lifetime(self) -> ast::Lifetime {
+        ast::Lifetime {
+            id: ast::DUMMY_NODE_ID,
+            span: DUMMY_SP,
+            name: self.to_name(),
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub trait IntoLifetimeDef {
+    fn into_lifetime_def(self) -> ast::LifetimeDef;
+}
+
+impl IntoLifetimeDef for ast::LifetimeDef {
+    fn into_lifetime_def(self) -> ast::LifetimeDef {
+        self
+    }
+}
+
+impl IntoLifetimeDef for ast::Lifetime {
+    fn into_lifetime_def(self) -> ast::LifetimeDef {
+        ast::LifetimeDef {
+            attrs: ast::ThinVec::new(),
+            lifetime: self,
+            bounds: vec![],
+        }
+    }
+}
+
+impl<'a> IntoLifetimeDef for &'a str {
+    fn into_lifetime_def(self) -> ast::LifetimeDef {
+        self.into_lifetime().into_lifetime_def()
+    }
+}
+
+impl IntoLifetimeDef for String {
+    fn into_lifetime_def(self) -> ast::LifetimeDef {
+        (*self).into_lifetime().into_lifetime_def()
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct LifetimeDefBuilder<F=Identity> {
+    callback: F,
+    lifetime: ast::Lifetime,
+    bounds: Vec<ast::Lifetime>,
+}
+
+impl LifetimeDefBuilder {
+    pub fn new<N>(name: N) -> Self
+        where N: ToName,
+    {
+        LifetimeDefBuilder::with_callback(name, Identity)
+    }
+}
+
+impl<F> LifetimeDefBuilder<F>
+    where F: Invoke<ast::LifetimeDef>,
+{
+    pub fn with_callback<N>(name: N, callback: F) -> Self
+        where N: ToName,
+    {
+        let lifetime = ast::Lifetime {
+            id: ast::DUMMY_NODE_ID,
+            span: DUMMY_SP,
+            name: name.to_name(),
+        };
+
+        LifetimeDefBuilder {
+            callback: callback,
+            lifetime: lifetime,
+            bounds: Vec::new(),
+        }
+    }
+
+    pub fn bound<N>(mut self, name: N) -> Self
+        where N: ToName,
+    {
+        let lifetime = ast::Lifetime {
+            id: ast::DUMMY_NODE_ID,
+            span: DUMMY_SP,
+            name: name.to_name(),
+        };
+
+        self.bounds.push(lifetime);
+        self
+    }
+
+    pub fn build(self) -> F::Result {
+        self.callback.invoke(ast::LifetimeDef {
+            attrs: ast::ThinVec::new(),
+            lifetime: self.lifetime,
+            bounds: self.bounds,
+        })
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/lit.rs
@@ -0,0 +1,153 @@
+use std::convert::Into;
+use std::rc::Rc;
+
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span};
+use syntax::ptr::P;
+
+use invoke::{Invoke, Identity};
+
+use str::ToInternedString;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct LitBuilder<F=Identity> {
+    callback: F,
+    span: Span,
+}
+
+impl LitBuilder {
+    pub fn new() -> LitBuilder {
+        LitBuilder::with_callback(Identity)
+    }
+}
+
+impl<F> LitBuilder<F>
+    where F: Invoke<P<ast::Lit>>,
+{
+    pub fn with_callback(callback: F) -> Self {
+        LitBuilder {
+            callback: callback,
+            span: DUMMY_SP,
+        }
+    }
+
+    pub fn span(mut self, span: Span) -> LitBuilder<F> {
+        self.span = span;
+        self
+    }
+
+    pub fn build_lit(self, lit: ast::LitKind) -> F::Result {
+        self.callback.invoke(P(ast::Lit {
+            span: self.span,
+            node: lit,
+        }))
+    }
+
+    pub fn bool(self, value: bool) -> F::Result {
+        self.build_lit(ast::LitKind::Bool(value))
+    }
+
+    pub fn true_(self) -> F::Result {
+        self.bool(true)
+    }
+
+    pub fn false_(self) -> F::Result {
+        self.bool(false)
+    }
+
+    pub fn int(self, value: u64) -> F::Result {
+        self.build_lit(ast::LitKind::Int(value, ast::LitIntType::Unsuffixed))
+    }
+
+    fn build_int(self, value: u64, ty: ast::IntTy) -> F::Result {
+        self.build_lit(ast::LitKind::Int(value, ast::LitIntType::Signed(ty)))
+    }
+
+    pub fn isize(self, value: usize) -> F::Result {
+        self.build_int(value as u64, ast::IntTy::Is)
+    }
+
+    pub fn i8(self, value: u8) -> F::Result {
+        self.build_int(value as u64, ast::IntTy::I8)
+    }
+
+    pub fn i16(self, value: u16) -> F::Result {
+        self.build_int(value as u64, ast::IntTy::I16)
+    }
+
+    pub fn i32(self, value: u32) -> F::Result {
+        self.build_int(value as u64, ast::IntTy::I32)
+    }
+
+    pub fn i64(self, value: u64) -> F::Result {
+        self.build_int(value as u64, ast::IntTy::I64)
+    }
+
+    pub fn uint(self, value: u64) -> F::Result {
+        self.build_lit(ast::LitKind::Int(value, ast::LitIntType::Unsuffixed))
+    }
+
+    fn build_uint(self, value: u64, ty: ast::UintTy) -> F::Result {
+        self.build_lit(ast::LitKind::Int(value, ast::LitIntType::Unsigned(ty)))
+    }
+
+    pub fn usize(self, value: usize) -> F::Result {
+        self.build_uint(value as u64, ast::UintTy::Us)
+    }
+
+    pub fn u8(self, value: u8) -> F::Result {
+        self.build_uint(value as u64, ast::UintTy::U8)
+    }
+
+    pub fn u16(self, value: u16) -> F::Result {
+        self.build_uint(value as u64, ast::UintTy::U16)
+    }
+
+    pub fn u32(self, value: u32) -> F::Result {
+        self.build_uint(value as u64, ast::UintTy::U32)
+    }
+
+    pub fn u64(self, value: u64) -> F::Result {
+        self.build_uint(value, ast::UintTy::U64)
+    }
+
+    fn build_float<S>(self, value: S, ty: ast::FloatTy) -> F::Result
+        where S: ToInternedString,
+    {
+        self.build_lit(ast::LitKind::Float(value.to_interned_string(), ty))
+    }
+
+    pub fn f32<S>(self, value: S) -> F::Result
+        where S: ToInternedString,
+    {
+        self.build_float(value, ast::FloatTy::F32)
+    }
+
+    pub fn f64<S>(self, value: S) -> F::Result
+        where S: ToInternedString,
+    {
+        self.build_float(value, ast::FloatTy::F64)
+    }
+
+    pub fn char(self, value: char) -> F::Result {
+        self.build_lit(ast::LitKind::Char(value))
+    }
+
+    pub fn byte(self, value: u8) -> F::Result {
+        self.build_lit(ast::LitKind::Byte(value))
+    }
+
+    pub fn str<S>(self, value: S) -> F::Result
+        where S: ToInternedString,
+    {
+        let value = value.to_interned_string();
+        self.build_lit(ast::LitKind::Str(value, ast::StrStyle::Cooked))
+    }
+
+    pub fn byte_str<T>(self, value: T) -> F::Result
+        where T: Into<Vec<u8>>,
+    {
+        self.build_lit(ast::LitKind::ByteStr(Rc::new(value.into())))
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/mac.rs
@@ -0,0 +1,144 @@
+use syntax::ast;
+use syntax::codemap::{self, DUMMY_SP, Span, respan};
+use syntax::ext::base::{DummyResolver, ExtCtxt};
+use syntax::ext::expand;
+use syntax::ext::quote::rt::ToTokens;
+use syntax::parse::ParseSess;
+use syntax::ptr::P;
+use syntax::tokenstream::TokenTree;
+
+use expr::ExprBuilder;
+use invoke::{Invoke, Identity};
+use name::ToName;
+use path::PathBuilder;
+
+/// A Builder for macro invocations.
+///
+/// Note that there are no commas added between args, as otherwise
+/// that macro invocations that could be expressed would be limited.
+/// You will need to add all required symbols with `with_arg` or
+/// `with_argss`.
+pub struct MacBuilder<F=Identity> {
+    callback: F,
+    span: Span,
+}
+
+impl MacBuilder {
+    pub fn new() -> Self {
+        MacBuilder::with_callback(Identity)
+    }
+}
+
+impl<F> MacBuilder<F>
+    where F: Invoke<ast::Mac>
+{
+    pub fn with_callback(callback: F) -> Self {
+        MacBuilder {
+            callback: callback,
+            span: DUMMY_SP,
+        }
+    }
+
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn build_path(self, path: ast::Path) -> MacPathBuilder<F> {
+        MacPathBuilder {
+            callback: self.callback,
+            span: self.span,
+            path: path,
+            tokens: vec![],
+        }
+    }
+
+    pub fn path(self) -> PathBuilder<Self> {
+        let span = self.span;
+        PathBuilder::with_callback(self).span(span)
+    }
+}
+
+impl<F> Invoke<ast::Path> for MacBuilder<F>
+    where F: Invoke<ast::Mac>,
+{
+    type Result = MacPathBuilder<F>;
+
+    fn invoke(self, path: ast::Path) -> Self::Result {
+        self.build_path(path)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct MacPathBuilder<F> {
+    callback: F,
+    span: Span,
+    path: ast::Path,
+    tokens: Vec<TokenTree>,
+}
+
+impl<F> MacPathBuilder<F>
+    where F: Invoke<ast::Mac>,
+{
+    pub fn with_args<I, T>(self, iter: I) -> Self
+        where I: IntoIterator<Item=T>, T: ToTokens
+    {
+        iter.into_iter().fold(self, |self_, expr| self_.with_arg(expr))
+    }
+
+    pub fn with_arg<T>(mut self, expr: T) -> Self
+        where T: ToTokens
+    {
+        let parse_sess = ParseSess::new();
+        let mut macro_loader = DummyResolver;
+        let cx = make_ext_ctxt(&parse_sess, &mut macro_loader);
+        let tokens = expr.to_tokens(&cx);
+        assert!(tokens.len() == 1);
+        self.tokens.push(tokens[0].clone());
+        self
+    }
+
+    pub fn expr(self) -> ExprBuilder<Self> {
+        let span = self.span;
+        ExprBuilder::with_callback(self).span(span)
+    }
+
+    pub fn build(self) -> F::Result {
+        let mac = ast::Mac_ {
+            path: self.path,
+            tts: self.tokens,
+        };
+        self.callback.invoke(respan(self.span, mac))
+    }
+}
+
+impl<F> Invoke<P<ast::Expr>> for MacPathBuilder<F>
+    where F: Invoke<ast::Mac>,
+{
+    type Result = Self;
+
+    fn invoke(self, expr: P<ast::Expr>) -> Self {
+        self.with_arg(expr)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+fn make_ext_ctxt<'a>(sess: &'a ParseSess,
+                     macro_loader: &'a mut DummyResolver) -> ExtCtxt<'a> {
+    let info = codemap::ExpnInfo {
+        call_site: codemap::DUMMY_SP,
+        callee: codemap::NameAndSpan {
+            format: codemap::MacroAttribute("test".to_name()),
+            allow_internal_unstable: false,
+            span: None
+        }
+    };
+
+    let ecfg = expand::ExpansionConfig::default(String::new());
+    let mut cx = ExtCtxt::new(sess, ecfg, macro_loader);
+    cx.bt_push(info);
+
+    cx
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/method.rs
@@ -0,0 +1,103 @@
+use syntax::abi::Abi;
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, respan, Span};
+use syntax::ptr::P;
+
+use fn_decl::FnDeclBuilder;
+use generics::GenericsBuilder;
+use invoke::{Invoke, Identity};
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct MethodSigBuilder<F=Identity> {
+    callback: F,
+    span: Span,
+    abi: Abi,
+    generics: ast::Generics,
+    unsafety: ast::Unsafety,
+    constness: ast::Constness,
+}
+
+impl MethodSigBuilder {
+    pub fn new() -> Self {
+        MethodSigBuilder::with_callback(Identity)
+    }
+}
+
+impl<F> MethodSigBuilder<F>
+    where F: Invoke<ast::MethodSig>,
+{
+    pub fn with_callback(callback: F) -> Self {
+        MethodSigBuilder {
+            callback: callback,
+            span: DUMMY_SP,
+            abi: Abi::Rust,
+            generics: GenericsBuilder::new().build(),
+            unsafety: ast::Unsafety::Normal,
+            constness: ast::Constness::NotConst,
+        }
+    }
+
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn unsafe_(mut self) -> Self {
+        self.unsafety = ast::Unsafety::Unsafe;
+        self
+    }
+
+    pub fn const_(mut self) -> Self {
+        self.constness = ast::Constness::Const;
+        self
+    }
+
+    pub fn abi(mut self, abi: Abi) -> Self {
+        self.abi = abi;
+        self
+    }
+
+    pub fn with_generics(mut self, generics: ast::Generics) -> Self {
+        self.generics = generics;
+        self
+    }
+
+    pub fn generics(self) -> GenericsBuilder<Self> {
+        GenericsBuilder::with_callback(self)
+    }
+
+    pub fn build_fn_decl(self, fn_decl: P<ast::FnDecl>) -> F::Result {
+        self.callback.invoke(ast::MethodSig {
+            unsafety: self.unsafety,
+            constness: respan(self.span, self.constness),
+            abi: self.abi,
+            decl: fn_decl,
+            generics: self.generics,
+        })
+    }
+
+    pub fn fn_decl(self) -> FnDeclBuilder<Self> {
+        FnDeclBuilder::with_callback(self)
+    }
+}
+
+impl<F> Invoke<ast::Generics> for MethodSigBuilder<F>
+    where F: Invoke<ast::MethodSig>,
+{
+    type Result = Self;
+
+    fn invoke(self, generics: ast::Generics) -> Self {
+        self.with_generics(generics)
+    }
+}
+
+impl<F> Invoke<P<ast::FnDecl>> for MethodSigBuilder<F>
+    where F: Invoke<ast::MethodSig>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, fn_decl: P<ast::FnDecl>) -> Self::Result {
+        self.build_fn_decl(fn_decl)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/name.rs
@@ -0,0 +1,32 @@
+use syntax::ast;
+use syntax::parse::token;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub trait ToName {
+    fn to_name(&self) -> ast::Name;
+}
+
+impl ToName for ast::Name {
+    fn to_name(&self) -> ast::Name {
+        *self
+    }
+}
+
+impl<'a> ToName for &'a str {
+    fn to_name(&self) -> ast::Name {
+        token::intern(*self)
+    }
+}
+
+impl<'a, T> ToName for &'a T where T: ToName {
+    fn to_name(&self) -> ast::Name {
+        (**self).to_name()
+    }
+}
+
+impl<'a, T> ToName for &'a mut T where T: ToName {
+    fn to_name(&self) -> ast::Name {
+        (**self).to_name()
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/pat.rs
@@ -0,0 +1,558 @@
+use std::iter::IntoIterator;
+
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span, Spanned, respan};
+use syntax::ptr::P;
+
+use invoke::{Invoke, Identity};
+
+use expr::ExprBuilder;
+use ident::ToIdent;
+use path::PathBuilder;
+use qpath::QPathBuilder;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct PatBuilder<F=Identity> {
+    callback: F,
+    span: Span,
+}
+
+impl PatBuilder {
+    pub fn new() -> Self {
+        PatBuilder::with_callback(Identity)
+    }
+}
+
+impl<F> PatBuilder<F>
+    where F: Invoke<P<ast::Pat>>,
+{
+    pub fn with_callback(callback: F) -> Self {
+        PatBuilder {
+            callback: callback,
+            span: DUMMY_SP,
+        }
+    }
+
+    pub fn span(mut self, span: Span) -> Self {
+        self.span = span;
+        self
+    }
+
+    pub fn build(self, pat: P<ast::Pat>) -> F::Result {
+        self.callback.invoke(pat)
+    }
+
+    pub fn build_pat_kind(self, pat_kind: ast::PatKind) -> F::Result {
+        let span = self.span;
+        self.build(P(ast::Pat {
+            id: ast::DUMMY_NODE_ID,
+            node: pat_kind,
+            span: span,
+        }))
+    }
+
+    pub fn wild(self) -> F::Result {
+        self.build_pat_kind(ast::PatKind::Wild)
+    }
+
+    pub fn build_id<I>(self, mode: ast::BindingMode, id: I, sub: Option<P<ast::Pat>>) -> F::Result
+        where I: ToIdent,
+    {
+        let id = respan(self.span, id.to_ident());
+
+        self.build_pat_kind(ast::PatKind::Ident(mode, id, sub))
+    }
+
+    pub fn id<I>(self, id: I) -> F::Result
+        where I: ToIdent
+    {
+        let mode = ast::BindingMode::ByValue(ast::Mutability::Immutable);
+        self.build_id(mode, id, None)
+    }
+
+    pub fn mut_id<I>(self, id: I) -> F::Result
+        where I: ToIdent
+    {
+        let mode = ast::BindingMode::ByValue(ast::Mutability::Mutable);
+        self.build_id(mode, id, None)
+    }
+
+    pub fn ref_id<I>(self, id: I) -> F::Result
+        where I: ToIdent
+    {
+        let mode = ast::BindingMode::ByRef(ast::Mutability::Immutable);
+        self.build_id(mode, id, None)
+    }
+
+    pub fn ref_mut_id<I>(self, id: I) -> F::Result
+        where I: ToIdent
+    {
+        let mode = ast::BindingMode::ByRef(ast::Mutability::Mutable);
+        self.build_id(mode, id, None)
+    }
+
+    pub fn enum_(self) -> PathBuilder<PatEnumBuilder<F>> {
+        PathBuilder::with_callback(PatEnumBuilder(self))
+    }
+
+    pub fn struct_(self) -> PathBuilder<PatStructBuilder<F>> {
+        PathBuilder::with_callback(PatStructBuilder(self))
+    }
+
+    pub fn expr(self) -> ExprBuilder<PatExprBuilder<F>> {
+        ExprBuilder::with_callback(PatExprBuilder(self))
+    }
+
+    pub fn build_path(self, path: ast::Path) -> F::Result {
+        self.build_pat_kind(ast::PatKind::Path(None, path))
+    }
+
+    pub fn build_qpath(self, qself: ast::QSelf, path: ast::Path) -> F::Result {
+        self.build_pat_kind(ast::PatKind::Path(Some(qself), path))
+    }
+
+    pub fn path(self) -> PathBuilder<Self> {
+        PathBuilder::with_callback(self)
+    }
+
+    pub fn qpath(self) -> QPathBuilder<Self> {
+        QPathBuilder::with_callback(self)
+    }
+
+    pub fn build_range(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+        self.build_pat_kind(ast::PatKind::Range(lhs, rhs))
+    }
+
+    pub fn range(self) -> ExprBuilder<PatRangeBuilder<F>> {
+        ExprBuilder::with_callback(PatRangeBuilder(self))
+    }
+
+    pub fn tuple(self) -> PatTupleBuilder<F> {
+        PatTupleBuilder {
+            builder: self,
+            pats: Vec::new(),
+            wild: None,
+        }
+    }
+
+    pub fn ref_(self) -> PatBuilder<PatRefBuilder<F>> {
+        PatBuilder::with_callback(PatRefBuilder {
+            builder: self,
+            mutability: ast::Mutability::Immutable,
+        })
+    }
+
+    pub fn ref_mut(self) -> PatBuilder<PatRefBuilder<F>> {
+        PatBuilder::with_callback(PatRefBuilder {
+            builder: self,
+            mutability: ast::Mutability::Mutable,
+        })
+    }
+
+    pub fn some(self) -> PatBuilder<PatEnumPathPatBuilder<F>> {
+        let path = PathBuilder::new().span(self.span)
+            .global()
+            .ids(&["std", "option", "Option", "Some"])
+            .build();
+
+        let span = self.span;
+        PatBuilder::with_callback(PatEnumPathPatBuilder {
+            builder: self,
+            path: path,
+        }).span(span)
+    }
+
+    pub fn none(self) -> F::Result {
+        let path = PathBuilder::new().span(self.span)
+            .global()
+            .ids(&["std", "option", "Option", "None"])
+            .build();
+
+        self.enum_()
+            .build(path)
+            .build()
+    }
+
+    pub fn ok(self) -> PatBuilder<PatEnumPathPatBuilder<F>> {
+        let path = PathBuilder::new().span(self.span)
+            .global()
+            .ids(&["std", "result", "Result", "Ok"])
+            .build();
+
+        let span = self.span;
+        PatBuilder::with_callback(PatEnumPathPatBuilder {
+            builder: self,
+            path: path,
+        }).span(span)
+    }
+
+    pub fn err(self) -> PatBuilder<PatEnumPathPatBuilder<F>> {
+        let path = PathBuilder::new().span(self.span)
+            .global()
+            .ids(&["std", "result", "Result", "Err"])
+            .build();
+
+        let span = self.span;
+        PatBuilder::with_callback(PatEnumPathPatBuilder {
+            builder: self,
+            path: path,
+        }).span(span)
+    }
+}
+
+impl<F> Invoke<ast::Path> for PatBuilder<F>
+    where F: Invoke<P<ast::Pat>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, path: ast::Path) -> F::Result {
+        self.build_path(path)
+    }
+}
+
+impl<F> Invoke<(ast::QSelf, ast::Path)> for PatBuilder<F>
+    where F: Invoke<P<ast::Pat>>,
+{
+    type Result = F::Result;
+
+    fn invoke(self, (qself, path): (ast::QSelf, ast::Path)) -> F::Result {
+        self.build_qpath(qself, path)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct PatRangeBuilder<F>(PatBuilder<F>);
+
+impl<F> Invoke<P<ast::Expr>> for PatRangeBuilder<F>
+    where F: Invoke<P<ast::Pat>>
+{
+    type Result = ExprBuilder<PatRangeExprBuilder<F>>;
+
+    fn invoke(self, lhs: P<ast::Expr>) -> Self::Result {
+        ExprBuilder::with_callback(PatRangeExprBuilder {
+            builder: self.0,
+            lhs: lhs,
+        })
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct PatRangeExprBuilder<F> {
+    builder: PatBuilder<F>,
+    lhs: P<ast::Expr>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for PatRangeExprBuilder<F>
+    where F: Invoke<P<ast::Pat>>
+{
+    type Result = F::Result;
+
+    fn invoke(self, rhs: P<ast::Expr>) -> Self::Result {
+        self.builder.build_range(self.lhs, rhs)
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct PatEnumBuilder<F>(PatBuilder<F>);
+
+impl<F> Invoke<ast::Path> for PatEnumBuilder<F> {
+    type Result = PatEnumPathBuilder<F>;
+
+    fn invoke(self, path: ast::Path) -> PatEnumPathBuilder<F> {
+        PatEnumPathBuilder {
+            builder: self.0,
+            path: path,
+            pats: Vec::new(),
+            wild: None,
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct PatEnumPathBuilder<F> {
+    builder: PatBuilder<F>,
+    path: ast::Path,
+    pats: Vec<P<ast::Pat>>,
+    wild: Option<usize>,
+}
+
+impl<F> PatEnumPathBuilder<F>
+    where F: Invoke<P<ast::Pat>>,
+{
+    pub fn with_pats<I>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=P<ast::Pat>>,
+    {
+        self.pats.extend(iter);
+        self
+    }
+
+    pub fn with_pat(mut self, pat: P<ast::Pat>) -> Self {
+        self.pats.push(pat);
+        self
+    }
+
+    pub fn pat(self) -> PatBuilder<Self> {
+        PatBuilder::with_callback(self)
+    }
+
+    pub fn with_ids<I, T>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=T>,
+              T: ToIdent,
+    {
+        for id in iter {
+            self = self.id(id);
+        }
+        self
+    }
+
+    pub fn id<I>(self, id: I) -> Self
+        where I: ToIdent
+    {
+        self.pat().id(id)
+    }
+
+    pub fn wild(mut self) -> Self {
+        self.wild = Some(self.pats.len());
+        self
+    }
+
+    pub fn build(self) -> F::Result {
+        self.builder.build_pat_kind(ast::PatKind::TupleStruct(
+            self.path,
+            self.pats,
+            self.wild))
+    }
+}
+
+impl<F> Invoke<P<ast::Pat>> for PatEnumPathBuilder<F>
+    where F: Invoke<P<ast::Pat>>,
+{
+    type Result = Self;
+
+    fn invoke(mut self, pat: P<ast::Pat>) -> Self {
+        self.pats.push(pat);
+        self
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct PatEnumPathPatBuilder<F> {
+    builder: PatBuilder<F>,
+    path: ast::Path,
+}
+
+impl<F> Invoke<P<ast::Pat>> for PatEnumPathPatBuilder<F>
+    where F: Invoke<P<ast::Pat>>
+{
+    type Result = F::Result;
+
+    fn invoke(self, pat: P<ast::Pat>) -> F::Result {
+        self.builder.enum_()
+            .build(self.path)
+            .with_pat(pat)
+            .build()
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct PatStructBuilder<F>(PatBuilder<F>);
+
+impl<F> Invoke<ast::Path> for PatStructBuilder<F> {
+    type Result = PatStructPathBuilder<F>;
+
+    fn invoke(self, path: ast::Path) -> PatStructPathBuilder<F> {
+        PatStructPathBuilder {
+            builder: self.0,
+            path: path,
+            pats: Vec::new(),
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct PatStructPathBuilder<F> {
+    builder: PatBuilder<F>,
+    path: ast::Path,
+    pats: Vec<Spanned<ast::FieldPat>>,
+}
+
+impl<F> PatStructPathBuilder<F>
+    where F: Invoke<P<ast::Pat>>,
+{
+    pub fn with_field_pat(mut self, pat: ast::FieldPat) -> Self {
+        self.pats.push(respan(self.builder.span, pat));
+        self
+    }
+
+    pub fn with_pats<I, T>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=(T, P<ast::Pat>)>,
+              T: ToIdent,
+    {
+        for (id, pat) in iter {
+            self = self.pat(id).build(pat);
+        }
+        self
+    }
+
+    pub fn pat<I>(self, id: I) -> PatBuilder<PatStructFieldBuilder<F>>
+        where I: ToIdent,
+    {
+        PatBuilder::with_callback(PatStructFieldBuilder {
+            builder: self,
+            id: id.to_ident(),
+        })
+    }
+
+    pub fn with_ids<I, T>(mut self, iter: I) -> Self
+        where I: IntoIterator<Item=T>,
+              T: ToIdent,
+    {
+        for id in iter {
+            self = self.id(id);
+        }
+        self
+    }
+
+    pub fn mut_id<I>(self, id: I) -> Self
+        where I: ToIdent,
+    {
+        let id = id.to_ident();
+        let span = self.builder.span;
+        let pat = PatBuilder::new().span(span).mut_id(id);