]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #35166 - nikomatsakis:incr-comp-ice-34991-2, r=mw
authorbors <bors@rust-lang.org>
Tue, 9 Aug 2016 17:00:54 +0000 (10:00 -0700)
committerGitHub <noreply@github.com>
Tue, 9 Aug 2016 17:00:54 +0000 (10:00 -0700)
Address ICEs running w/ incremental compilation and building glium

Fixes for various ICEs I encountered trying to build glium with incremental compilation enabled. Building glium now works. Of the 4 ICEs, I have test cases for 3 of them -- I didn't isolate a test for the last commit and kind of want to go do other things -- most notably, figuring out why incremental isn't saving much *effort*.

But if it seems worthwhile and I can come back and try to narrow down the problem.

r? @michaelwoerister

Fixes #34991
Fixes #32015

325 files changed:
configure
man/rustc.1
man/rustdoc.1
mk/cfg/x86_64-unknown-linux-musl.mk
mk/main.mk
mk/rustllvm.mk
src/bootstrap/lib.rs
src/doc/book/guessing-game.md
src/doc/book/lang-items.md
src/doc/book/the-stack-and-the-heap.md
src/doc/reference.md
src/libcollections/range.rs
src/libcollections/slice.rs
src/libcollections/string.rs
src/libcollections/vec.rs
src/libcore/cell.rs
src/libcore/iter/traits.rs
src/libcore/marker.rs
src/libcore/raw.rs
src/libcore/slice.rs
src/libcore/sync/atomic.rs
src/librustc/diagnostics.rs
src/librustc/hir/mod.rs
src/librustc/middle/astconv_util.rs
src/librustc/middle/entry.rs
src/librustc/middle/stability.rs
src/librustc/session/config.rs
src/librustc/traits/error_reporting.rs
src/librustc/traits/object_safety.rs
src/librustc/ty/util.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_const_eval/check_match.rs
src/librustc_const_eval/diagnostics.rs
src/librustc_const_eval/eval.rs
src/librustc_const_math/err.rs
src/librustc_driver/driver.rs
src/librustc_driver/lib.rs
src/librustc_lint/builtin.rs
src/librustc_lint/lib.rs
src/librustc_llvm/build.rs
src/librustc_llvm/diagnostic.rs
src/librustc_llvm/ffi.rs [new file with mode: 0644]
src/librustc_llvm/lib.rs
src/librustc_mir/transform/deaggregator.rs [new file with mode: 0644]
src/librustc_mir/transform/mod.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_passes/ast_validation.rs
src/librustc_passes/consts.rs
src/librustc_passes/diagnostics.rs
src/librustc_passes/lib.rs
src/librustc_passes/loops.rs
src/librustc_passes/no_asm.rs
src/librustc_passes/static_recursion.rs
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/diagnostics.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/resolve_imports.rs
src/librustc_trans/abi.rs
src/librustc_trans/asm.rs
src/librustc_trans/attributes.rs
src/librustc_trans/back/archive.rs
src/librustc_trans/back/write.rs
src/librustc_trans/base.rs
src/librustc_trans/build.rs
src/librustc_trans/builder.rs
src/librustc_trans/closure.rs
src/librustc_trans/common.rs
src/librustc_trans/consts.rs
src/librustc_trans/context.rs
src/librustc_trans/debuginfo/create_scope_map.rs
src/librustc_trans/debuginfo/gdb.rs
src/librustc_trans/debuginfo/metadata.rs
src/librustc_trans/debuginfo/mod.rs
src/librustc_trans/debuginfo/namespace.rs
src/librustc_trans/debuginfo/source_loc.rs
src/librustc_trans/debuginfo/utils.rs
src/librustc_trans/declare.rs
src/librustc_trans/expr.rs
src/librustc_trans/intrinsic.rs
src/librustc_trans/mir/block.rs
src/librustc_trans/mir/constant.rs
src/librustc_trans/mir/mod.rs
src/librustc_trans/mir/rvalue.rs
src/librustc_trans/monomorphize.rs
src/librustc_trans/trans_item.rs
src/librustc_trans/type_.rs
src/librustc_trans/value.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/autoderef.rs
src/librustc_typeck/check/callee.rs
src/librustc_typeck/check/compare_method.rs
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/op.rs
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/coherence/orphan.rs
src/librustc_typeck/coherence/overlap.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/diagnostics.rs
src/librustc_typeck/lib.rs
src/libstd/error.rs
src/libstd/ffi/c_str.rs
src/libstd/fs.rs
src/libstd/io/error.rs
src/libstd/io/mod.rs
src/libstd/io/stdio.rs
src/libstd/lib.rs
src/libstd/net/mod.rs
src/libstd/net/tcp.rs
src/libstd/sys/common/wtf8.rs
src/libstd/sys/unix/fs.rs
src/libstd/sys/unix/os.rs
src/libstd/sys/unix/rwlock.rs
src/libstd/sys/windows/fs.rs
src/libstd/thread/mod.rs
src/libsyntax/codemap.rs
src/libsyntax/parse/mod.rs
src/libsyntax/tokenstream.rs
src/rustllvm/ArchiveWrapper.cpp
src/rustllvm/ExecutionEngineWrapper.cpp [deleted file]
src/rustllvm/PassWrapper.cpp
src/rustllvm/README
src/rustllvm/RustWrapper.cpp
src/rustllvm/rustllvm.h
src/test/compile-fail/E0010.rs
src/test/compile-fail/E0027.rs
src/test/compile-fail/E0029.rs
src/test/compile-fail/E0040.rs
src/test/compile-fail/E0046.rs
src/test/compile-fail/E0055.rs
src/test/compile-fail/E0060.rs
src/test/compile-fail/E0061.rs
src/test/compile-fail/E0062.rs
src/test/compile-fail/E0069.rs
src/test/compile-fail/E0071.rs
src/test/compile-fail/E0079.rs
src/test/compile-fail/E0101.rs
src/test/compile-fail/E0102.rs
src/test/compile-fail/E0106.rs
src/test/compile-fail/E0107.rs
src/test/compile-fail/E0109.rs
src/test/compile-fail/E0110.rs
src/test/compile-fail/E0116.rs
src/test/compile-fail/E0117.rs
src/test/compile-fail/E0118.rs
src/test/compile-fail/E0119.rs
src/test/compile-fail/E0120.rs
src/test/compile-fail/E0124.rs
src/test/compile-fail/E0131.rs
src/test/compile-fail/E0132.rs
src/test/compile-fail/E0137.rs
src/test/compile-fail/E0166.rs
src/test/compile-fail/E0172.rs
src/test/compile-fail/E0178.rs
src/test/compile-fail/E0185.rs
src/test/compile-fail/E0186.rs
src/test/compile-fail/E0201.rs [new file with mode: 0644]
src/test/compile-fail/E0204.rs [new file with mode: 0644]
src/test/compile-fail/E0205.rs [new file with mode: 0644]
src/test/compile-fail/E0206.rs [new file with mode: 0644]
src/test/compile-fail/E0207.rs [new file with mode: 0644]
src/test/compile-fail/E0214.rs [new file with mode: 0644]
src/test/compile-fail/E0220.rs [new file with mode: 0644]
src/test/compile-fail/E0221.rs [new file with mode: 0644]
src/test/compile-fail/E0223.rs [new file with mode: 0644]
src/test/compile-fail/E0225.rs [new file with mode: 0644]
src/test/compile-fail/E0229.rs [new file with mode: 0644]
src/test/compile-fail/E0232.rs [new file with mode: 0644]
src/test/compile-fail/E0243.rs [new file with mode: 0644]
src/test/compile-fail/E0244.rs [new file with mode: 0644]
src/test/compile-fail/E0248.rs [new file with mode: 0644]
src/test/compile-fail/E0252.rs [new file with mode: 0644]
src/test/compile-fail/E0253.rs [new file with mode: 0644]
src/test/compile-fail/E0254.rs [new file with mode: 0644]
src/test/compile-fail/E0255.rs [new file with mode: 0644]
src/test/compile-fail/E0259.rs [new file with mode: 0644]
src/test/compile-fail/E0260.rs [new file with mode: 0644]
src/test/compile-fail/E0261.rs [new file with mode: 0644]
src/test/compile-fail/E0262.rs [new file with mode: 0644]
src/test/compile-fail/E0263.rs [new file with mode: 0644]
src/test/compile-fail/E0264.rs [new file with mode: 0644]
src/test/compile-fail/E0267.rs [new file with mode: 0644]
src/test/compile-fail/E0268.rs [new file with mode: 0644]
src/test/compile-fail/E0271.rs [new file with mode: 0644]
src/test/compile-fail/E0275.rs [new file with mode: 0644]
src/test/compile-fail/E0276.rs [new file with mode: 0644]
src/test/compile-fail/E0277.rs [new file with mode: 0644]
src/test/compile-fail/E0281.rs [new file with mode: 0644]
src/test/compile-fail/E0282.rs [new file with mode: 0644]
src/test/compile-fail/E0283.rs [new file with mode: 0644]
src/test/compile-fail/E0296.rs [new file with mode: 0644]
src/test/compile-fail/E0297.rs [new file with mode: 0644]
src/test/compile-fail/E0301.rs [new file with mode: 0644]
src/test/compile-fail/E0302.rs [new file with mode: 0644]
src/test/compile-fail/E0303.rs [new file with mode: 0644]
src/test/compile-fail/E0306.rs [new file with mode: 0644]
src/test/compile-fail/E0308-2.rs [new file with mode: 0644]
src/test/compile-fail/E0308-3.rs [new file with mode: 0644]
src/test/compile-fail/E0308-4.rs [new file with mode: 0644]
src/test/compile-fail/E0308.rs [new file with mode: 0644]
src/test/compile-fail/associated-types-in-ambiguous-context.rs
src/test/compile-fail/bad-bang-ann-3.rs
src/test/compile-fail/borrowck/borrowck-escaping-closure-error-1.rs
src/test/compile-fail/borrowck/borrowck-escaping-closure-error-2.rs
src/test/compile-fail/coherence-impls-copy.rs
src/test/compile-fail/const-err-early.rs
src/test/compile-fail/const-err-multi.rs
src/test/compile-fail/const-err.rs
src/test/compile-fail/const-err2.rs
src/test/compile-fail/const-eval-overflow-2.rs
src/test/compile-fail/const-eval-overflow-3.rs
src/test/compile-fail/const-eval-overflow-4.rs
src/test/compile-fail/const-eval-overflow.rs
src/test/compile-fail/const-fn-mismatch.rs
src/test/compile-fail/const-integer-bool-ops.rs
src/test/compile-fail/const-len-underflow-separate-spans.rs
src/test/compile-fail/const-len-underflow-subspans.rs
src/test/compile-fail/const-pattern-irrefutable.rs
src/test/compile-fail/const-tup-index-span.rs
src/test/compile-fail/deprecation-lint-nested.rs [new file with mode: 0644]
src/test/compile-fail/deprecation-lint.rs
src/test/compile-fail/double-import.rs
src/test/compile-fail/enable-orbit-for-incr-comp.rs [new file with mode: 0644]
src/test/compile-fail/eval-enum.rs
src/test/compile-fail/generic-type-less-params-with-defaults.rs
src/test/compile-fail/generic-type-more-params-with-defaults.rs
src/test/compile-fail/impl-duplicate-methods.rs
src/test/compile-fail/impl-unused-rps-in-assoc-type.rs
src/test/compile-fail/impl-wrong-item-for-trait.rs
src/test/compile-fail/issue-12187-1.rs
src/test/compile-fail/issue-12187-2.rs
src/test/compile-fail/issue-14092.rs
src/test/compile-fail/issue-15524.rs
src/test/compile-fail/issue-18819.rs
src/test/compile-fail/issue-22886.rs
src/test/compile-fail/issue-23024.rs
src/test/compile-fail/issue-23041.rs
src/test/compile-fail/issue-23543.rs
src/test/compile-fail/issue-23544.rs
src/test/compile-fail/issue-23729.rs
src/test/compile-fail/issue-23827.rs
src/test/compile-fail/issue-24356.rs
src/test/compile-fail/issue-26886.rs
src/test/compile-fail/issue-27008.rs
src/test/compile-fail/issue-27340.rs
src/test/compile-fail/issue-28568.rs
src/test/compile-fail/issue-3044.rs
src/test/compile-fail/issue-31221.rs
src/test/compile-fail/issue-33784.rs [new file with mode: 0644]
src/test/compile-fail/issue-34209.rs
src/test/compile-fail/issue-35139.rs
src/test/compile-fail/issue-3907.rs
src/test/compile-fail/issue-4335.rs
src/test/compile-fail/issue-4935.rs
src/test/compile-fail/issue-5035.rs
src/test/compile-fail/issue-5062.rs
src/test/compile-fail/issue-5239-1.rs
src/test/compile-fail/issue-6458-2.rs
src/test/compile-fail/issue-6458-3.rs
src/test/compile-fail/issue-6458-4.rs
src/test/compile-fail/issue-6458.rs
src/test/compile-fail/issue-7813.rs
src/test/compile-fail/issue-8460-const.rs
src/test/compile-fail/lint-exceeding-bitshifts.rs
src/test/compile-fail/lint-type-overflow2.rs
src/test/compile-fail/lint-unused-imports.rs
src/test/compile-fail/method-ambig-one-trait-unknown-int-type.rs
src/test/compile-fail/method-call-err-msg.rs
src/test/compile-fail/no-patterns-in-args.rs [new file with mode: 0644]
src/test/compile-fail/non-exhaustive-pattern-witness.rs
src/test/compile-fail/not-enough-arguments.rs
src/test/compile-fail/overloaded-calls-bad.rs
src/test/compile-fail/qualified-path-params-2.rs
src/test/compile-fail/region-borrow-params-issue-29793-small.rs
src/test/compile-fail/regions-nested-fns-2.rs
src/test/compile-fail/repeat_count.rs
src/test/compile-fail/self-impl.rs
src/test/compile-fail/struct-fields-decl-dupe.rs
src/test/compile-fail/trait-as-struct-constructor.rs
src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs
src/test/compile-fail/typeck-builtin-bound-type-parameters.rs
src/test/compile-fail/typeck_type_placeholder_item.rs
src/test/compile-fail/typeck_type_placeholder_lifetime_1.rs
src/test/compile-fail/typeck_type_placeholder_lifetime_2.rs
src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs
src/test/compile-fail/unconstrained-none.rs
src/test/compile-fail/unconstrained-ref.rs
src/test/compile-fail/use-mod.rs
src/test/compile-fail/variadic-ffi-3.rs
src/test/compile-fail/vector-no-ann.rs
src/test/mir-opt/deaggregator_test.rs [new file with mode: 0644]
src/test/run-fail/divide-by-zero.rs
src/test/run-fail/mod-zero.rs
src/test/run-fail/overflowing-add.rs
src/test/run-fail/overflowing-lsh-1.rs
src/test/run-fail/overflowing-lsh-2.rs
src/test/run-fail/overflowing-lsh-3.rs
src/test/run-fail/overflowing-lsh-4.rs
src/test/run-fail/overflowing-mul.rs
src/test/run-fail/overflowing-neg.rs
src/test/run-fail/overflowing-pow.rs
src/test/run-fail/overflowing-rsh-1.rs
src/test/run-fail/overflowing-rsh-2.rs
src/test/run-fail/overflowing-rsh-3.rs
src/test/run-fail/overflowing-rsh-4.rs
src/test/run-fail/overflowing-rsh-5.rs
src/test/run-fail/overflowing-rsh-6.rs
src/test/run-fail/overflowing-sub.rs
src/test/run-pass/auxiliary/typeid-intrinsic-aux1.rs
src/test/run-pass/auxiliary/typeid-intrinsic-aux2.rs
src/test/run-pass/issue-14936.rs
src/test/run-pass/issue-20847.rs [new file with mode: 0644]
src/test/run-pass/issue-28950.rs
src/test/run-pass/mir_cross_crate.rs [new file with mode: 0644]
src/test/run-pass/mir_overflow_off.rs [new file with mode: 0644]
src/test/run-pass/simd-upgraded.rs [new file with mode: 0644]
src/test/run-pass/slice_binary_search.rs [new file with mode: 0644]
src/test/run-pass/type-id-higher-rank-2.rs [new file with mode: 0644]
src/test/run-pass/type-id-higher-rank.rs
src/test/run-pass/typeid-intrinsic.rs
src/test/ui/codemap_tests/two_files.stderr
src/tools/cargotest/main.rs
src/tools/compiletest/src/runtest.rs

index d4bd16167d35cba350c1e042b12e1b189a8a720a..29f16da058129f917ae7e667a346a6020b5e0334 100755 (executable)
--- a/configure
+++ b/configure
@@ -609,7 +609,7 @@ opt dist-host-only 0 "only install bins for the host architecture"
 opt inject-std-version 1 "inject the current compiler version of libstd into programs"
 opt llvm-version-check 1 "check if the LLVM version is supported, build anyway"
 opt rustbuild 0 "use the rust and cargo based build system"
-opt orbit 0 "get MIR where it belongs - everywhere; most importantly, in orbit"
+opt orbit 1 "get MIR where it belongs - everywhere; most importantly, in orbit"
 opt codegen-tests 1 "run the src/test/codegen tests"
 opt option-checking 1 "complain about unrecognized options in this configure script"
 opt ninja 0 "build LLVM using the Ninja generator (for MSVC, requires building in the correct environment)"
@@ -733,7 +733,7 @@ if [ -n "$CFG_ENABLE_DEBUG_ASSERTIONS" ]; then putvar CFG_ENABLE_DEBUG_ASSERTION
 if [ -n "$CFG_ENABLE_DEBUGINFO" ]; then putvar CFG_ENABLE_DEBUGINFO; fi
 if [ -n "$CFG_ENABLE_DEBUG_JEMALLOC" ]; then putvar CFG_ENABLE_DEBUG_JEMALLOC; fi
 
-if [ -n "$CFG_ENABLE_ORBIT" ]; then putvar CFG_ENABLE_ORBIT; fi
+if [ -n "$CFG_DISABLE_ORBIT" ]; then putvar CFG_DISABLE_ORBIT; fi
 
 step_msg "looking for build programs"
 
index fa61afd3be582215f26ea7262452c8c177e56f5b..edbc6cea0266499c582036320c4b954489dd328f 100644 (file)
@@ -1,4 +1,4 @@
-.TH RUSTC "1" "August 2015" "rustc 1.2.0" "User Commands"
+.TH RUSTC "1" "August 2016" "rustc 1.12.0" "User Commands"
 .SH NAME
 rustc \- The Rust compiler
 .SH SYNOPSIS
@@ -299,7 +299,7 @@ To build an executable with debug info:
 See https://github.com/rust\-lang/rust/issues for issues.
 
 .SH "AUTHOR"
-See \fIAUTHORS.txt\fR in the Rust source distribution.
+See https://github.com/rust\-lang/rust/graphs/contributors or use `git log --all --format='%cN <%cE>' | sort -u` in the rust source distribution.
 
 .SH "COPYRIGHT"
 This work is dual\[hy]licensed under Apache\ 2.0 and MIT terms.
index ae14c9d78287f3833965b734fb4a846c4b163155..3fb5757f4ff24be21f2cac4ea3312fef2d257b23 100644 (file)
@@ -1,4 +1,4 @@
-.TH RUSTDOC "1" "August 2015" "rustdoc 1.2.0" "User Commands"
+.TH RUSTDOC "1" "August 2016" "rustdoc 1.12.0" "User Commands"
 .SH NAME
 rustdoc \- generate documentation from Rust source code
 .SH SYNOPSIS
index 3a03b2accd541449456dcadc2d86b4d11d363cee..6f707ac3b3fb8512fa4b67e86b77816ee1589979 100644 (file)
@@ -7,8 +7,8 @@ CFG_INSTALL_ONLY_RLIB_x86_64-unknown-linux-musl = 1
 CFG_LIB_NAME_x86_64-unknown-linux-musl=lib$(1).so
 CFG_STATIC_LIB_NAME_x86_64-unknown-linux-musl=lib$(1).a
 CFG_LIB_GLOB_x86_64-unknown-linux-musl=lib$(1)-*.so
-CFG_JEMALLOC_CFLAGS_x86_64-unknown-linux-musl := -m64
-CFG_GCCISH_CFLAGS_x86_64-unknown-linux-musl :=  -g -fPIC -m64
+CFG_JEMALLOC_CFLAGS_x86_64-unknown-linux-musl := -m64 -Wa,-mrelax-relocations=no
+CFG_GCCISH_CFLAGS_x86_64-unknown-linux-musl :=  -g -fPIC -m64 -Wa,-mrelax-relocations=no
 CFG_GCCISH_CXXFLAGS_x86_64-unknown-linux-musl :=
 CFG_GCCISH_LINK_FLAGS_x86_64-unknown-linux-musl :=
 CFG_GCCISH_DEF_FLAG_x86_64-unknown-linux-musl :=
index fd12bf26dfc72fdca793e5efa4ae459c24320819..c6c3e70abc37ae50c2e7c0f56e1aab0ea0d9b11a 100644 (file)
@@ -162,9 +162,10 @@ ifdef CFG_ENABLE_DEBUGINFO
   CFG_RUSTC_FLAGS += -g
 endif
 
-ifdef CFG_ENABLE_ORBIT
-  $(info cfg: launching MIR (CFG_ENABLE_ORBIT))
-  CFG_RUSTC_FLAGS += -Z orbit
+ifdef CFG_DISABLE_ORBIT
+  $(info cfg: HOLD HOLD HOLD (CFG_DISABLE_ORBIT))
+  RUSTFLAGS_STAGE1 += -Z orbit=off
+  RUSTFLAGS_STAGE2 += -Z orbit=off
 endif
 
 ifdef SAVE_TEMPS
index 834a11d37fa40d18e0c4f79df8dc2821f50f7018..b50dbd01ad0cc0071bcf20cf8b5ba366ca724dc2 100644 (file)
@@ -24,7 +24,7 @@ LLVM_EXTRA_INCDIRS_$(1)= $$(call CFG_CC_INCLUDE_$(1),$(S)src/llvm/include) \
 endif
 
 RUSTLLVM_OBJS_CS_$(1) := $$(addprefix rustllvm/, \
-       ExecutionEngineWrapper.cpp RustWrapper.cpp PassWrapper.cpp \
+       RustWrapper.cpp PassWrapper.cpp \
        ArchiveWrapper.cpp)
 
 RUSTLLVM_INCS_$(1) = $$(LLVM_EXTRA_INCDIRS_$(1)) \
index 25356b86221c1975e4b59ee6d31901611852752c..acb7e0fadd90a5049aeed4de71982625d2cc5a75 100644 (file)
@@ -855,6 +855,12 @@ fn cflags(&self, target: &str) -> Vec<String> {
             base.push("-stdlib=libc++".into());
             base.push("-mmacosx-version-min=10.7".into());
         }
+        // This is a hack, because newer binutils broke things on some vms/distros
+        // (i.e., linking against unknown relocs disabled by the following flag)
+        // See: https://github.com/rust-lang/rust/issues/34978
+        if target == "x86_64-unknown-linux-musl" {
+            base.push("-Wa,-mrelax-relocations=no".into());
+        }
         return base
     }
 
index 6ce75efd1031d83ce7d372081090542a6091bf9b..22cf6068e4d5a20f79fa61075ed31fa23e10b5b8 100644 (file)
@@ -365,7 +365,7 @@ numbers. A bare number like above is actually shorthand for `^0.3.0`,
 meaning "anything compatible with 0.3.0".
 If we wanted to use only `0.3.0` exactly, we could say `rand="=0.3.0"`
 (note the two equal signs).
-And if we wanted to use the latest version we could use `*`.
+And if we wanted to use the latest version we could use `rand="*"`.
 We could also use a range of versions.
 [Cargo’s documentation][cargodoc] contains more details.
 
index b948567ac5b74a565a55d6136081e763aec8d997..72a3c08225d035866f8269f273b4a00839492295 100644 (file)
@@ -15,7 +15,7 @@ For example, `Box` pointers require two lang items, one for allocation
 and one for deallocation. A freestanding program that uses the `Box`
 sugar for dynamic allocations via `malloc` and `free`:
 
-```rust
+```rust,ignore
 #![feature(lang_items, box_syntax, start, libc)]
 #![no_std]
 
index a1f6a065a252bd93d6dabd58e4064b03be525702..aee45299cf22d77369fde008fc9b2cba292f7058 100644 (file)
@@ -26,6 +26,8 @@ The stack is very fast, and is where memory is allocated in Rust by default.
 But the allocation is local to a function call, and is limited in size. The
 heap, on the other hand, is slower, and is explicitly allocated by your
 program. But it’s effectively unlimited in size, and is globally accessible.
+Note this meaning of heap, which allocates arbitrary-sized blocks of memory in arbitrary
+order, is quite different from the heap data structure.  
 
 # The Stack
 
index a461023642afd6130df80eaf0b95de7c0cd32021..f4ffe5774d27cd0f3dd121f42bb89255e0e11da6 100644 (file)
@@ -3049,7 +3049,8 @@ as
 == != < > <= >=
 &&
 ||
-= ..
+.. ...
+=
 ```
 
 Operators at the same precedence level are evaluated left-to-right. [Unary
index 4e39191b472ee8f6a85ec7ea67a21fbc0745c6d7..1badc72aed07c1a9d21eab781c59fd6ef5fed9f9 100644 (file)
@@ -23,6 +23,22 @@ pub trait RangeArgument<T> {
     /// Start index (inclusive)
     ///
     /// Return start value if present, else `None`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(collections)]
+    /// #![feature(collections_range)]
+    ///
+    /// extern crate collections;
+    ///
+    /// # fn main() {
+    /// use collections::range::RangeArgument;
+    ///
+    /// assert_eq!((..10).start(), None);
+    /// assert_eq!((3..10).start(), Some(&3));
+    /// # }
+    /// ```
     fn start(&self) -> Option<&T> {
         None
     }
@@ -30,6 +46,22 @@ fn start(&self) -> Option<&T> {
     /// End index (exclusive)
     ///
     /// Return end value if present, else `None`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(collections)]
+    /// #![feature(collections_range)]
+    ///
+    /// extern crate collections;
+    ///
+    /// # fn main() {
+    /// use collections::range::RangeArgument;
+    ///
+    /// assert_eq!((3..).end(), None);
+    /// assert_eq!((3..10).end(), Some(&10));
+    /// # }
+    /// ```
     fn end(&self) -> Option<&T> {
         None
     }
index ff2b8cdea22789076a31416392827ecfee6ba742..5cdf4ee88c00cd511016b2620908251d1f0dc126 100644 (file)
@@ -973,8 +973,8 @@ pub fn binary_search(&self, x: &T) -> Result<usize, usize>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn binary_search_by<F>(&self, f: F) -> Result<usize, usize>
-        where F: FnMut(&T) -> Ordering
+    pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
+        where F: FnMut(&'a T) -> Ordering
     {
         core_slice::SliceExt::binary_search_by(self, f)
     }
@@ -1009,8 +1009,8 @@ pub fn binary_search_by<F>(&self, f: F) -> Result<usize, usize>
     /// ```
     #[stable(feature = "slice_binary_search_by_key", since = "1.10.0")]
     #[inline]
-    pub fn binary_search_by_key<B, F>(&self, b: &B, f: F) -> Result<usize, usize>
-        where F: FnMut(&T) -> B,
+    pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, f: F) -> Result<usize, usize>
+        where F: FnMut(&'a T) -> B,
               B: Ord
     {
         core_slice::SliceExt::binary_search_by_key(self, b, f)
index f91d8a5f4e1e84d506fd4562fa69f27d87b4c72d..70b514afd035f1d17d446c0dbbee6f158b1eb950 100644 (file)
@@ -1874,6 +1874,27 @@ fn from(s: String) -> Cow<'a, str> {
     }
 }
 
+#[stable(feature = "cow_str_from_iter", since = "1.12.0")]
+impl<'a> FromIterator<char> for Cow<'a, str> {
+    fn from_iter<I: IntoIterator<Item = char>>(it: I) -> Cow<'a, str> {
+        Cow::Owned(FromIterator::from_iter(it))
+    }
+}
+
+#[stable(feature = "cow_str_from_iter", since = "1.12.0")]
+impl<'a, 'b> FromIterator<&'b str> for Cow<'a, str> {
+    fn from_iter<I: IntoIterator<Item = &'b str>>(it: I) -> Cow<'a, str> {
+        Cow::Owned(FromIterator::from_iter(it))
+    }
+}
+
+#[stable(feature = "cow_str_from_iter", since = "1.12.0")]
+impl<'a> FromIterator<String> for Cow<'a, str> {
+    fn from_iter<I: IntoIterator<Item = String>>(it: I) -> Cow<'a, str> {
+        Cow::Owned(FromIterator::from_iter(it))
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Into<Vec<u8>> for String {
     fn into(self) -> Vec<u8> {
@@ -1881,6 +1902,26 @@ fn into(self) -> Vec<u8> {
     }
 }
 
+#[stable(feature = "stringfromchars", since = "1.12.0")]
+impl<'a> From<&'a [char]> for String {
+    #[inline]
+    fn from(v: &'a [char]) -> String {
+        let mut s = String::with_capacity(v.len());
+        for c in v {
+            s.push(*c);
+        }
+        s
+    }
+}
+
+#[stable(feature = "stringfromchars", since = "1.12.0")]
+impl From<Vec<char>> for String {
+    #[inline]
+    fn from(v: Vec<char>) -> String {
+        String::from(v.as_slice())
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Write for String {
     #[inline]
index 275f38b2f787d469a8596be0b0d6bcce64fc3b19..8b4fce158de4645d60b1557bde684283d0d21509 100644 (file)
@@ -476,6 +476,25 @@ pub fn shrink_to_fit(&mut self) {
     /// Note that this will drop any excess capacity. Calling this and
     /// converting back to a vector with `into_vec()` is equivalent to calling
     /// `shrink_to_fit()`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let v = vec![1, 2, 3];
+    ///
+    /// let slice = v.into_boxed_slice();
+    /// ```
+    ///
+    /// Any excess capacity is removed:
+    ///
+    /// ```
+    /// let mut vec = Vec::with_capacity(10);
+    /// vec.extend([1, 2, 3].iter().cloned());
+    ///
+    /// assert_eq!(vec.capacity(), 10);
+    /// let slice = vec.into_boxed_slice();
+    /// assert_eq!(slice.into_vec().capacity(), 3);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_boxed_slice(mut self) -> Box<[T]> {
         unsafe {
index 65cb1aaaff6fd1e729d0e9a4ceb9a09ca57269a8..434084d3af8653f9888fb3f41cc75c1a19f5ffd2 100644 (file)
 use clone::Clone;
 use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
 use default::Default;
-use marker::{Copy, Send, Sync, Sized, Unsize};
+use fmt::{self, Debug, Display};
+use marker::{Copy, PhantomData, Send, Sync, Sized, Unsize};
 use ops::{Deref, DerefMut, Drop, FnOnce, CoerceUnsized};
 use option::Option;
 use option::Option::{None, Some};
+use result::Result;
+use result::Result::{Ok, Err};
 
 /// A mutable memory location that admits only `Copy` data.
 ///
@@ -347,6 +350,46 @@ pub enum BorrowState {
     Unused,
 }
 
+/// An error returned by [`RefCell::try_borrow`](struct.RefCell.html#method.try_borrow).
+#[unstable(feature = "try_borrow", issue = "35070")]
+pub struct BorrowError<'a, T: 'a + ?Sized> {
+    marker: PhantomData<&'a RefCell<T>>,
+}
+
+#[unstable(feature = "try_borrow", issue = "35070")]
+impl<'a, T: ?Sized> Debug for BorrowError<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("BorrowError").finish()
+    }
+}
+
+#[unstable(feature = "try_borrow", issue = "35070")]
+impl<'a, T: ?Sized> Display for BorrowError<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        Display::fmt("already mutably borrowed", f)
+    }
+}
+
+/// An error returned by [`RefCell::try_borrow_mut`](struct.RefCell.html#method.try_borrow_mut).
+#[unstable(feature = "try_borrow", issue = "35070")]
+pub struct BorrowMutError<'a, T: 'a + ?Sized> {
+    marker: PhantomData<&'a RefCell<T>>,
+}
+
+#[unstable(feature = "try_borrow", issue = "35070")]
+impl<'a, T: ?Sized> Debug for BorrowMutError<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("BorrowMutError").finish()
+    }
+}
+
+#[unstable(feature = "try_borrow", issue = "35070")]
+impl<'a, T: ?Sized> Display for BorrowMutError<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        Display::fmt("already borrowed", f)
+    }
+}
+
 // Values [1, MAX-1] represent the number of `Ref` active
 // (will not outgrow its range since `usize` is the size of the address space)
 type BorrowFlag = usize;
@@ -432,7 +475,8 @@ pub fn borrow_state(&self) -> BorrowState {
     ///
     /// # Panics
     ///
-    /// Panics if the value is currently mutably borrowed.
+    /// Panics if the value is currently mutably borrowed. For a non-panicking variant, use
+    /// [`try_borrow`](#method.try_borrow).
     ///
     /// # Examples
     ///
@@ -463,12 +507,45 @@ pub fn borrow_state(&self) -> BorrowState {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn borrow(&self) -> Ref<T> {
+        self.try_borrow().expect("already mutably borrowed")
+    }
+
+    /// Immutably borrows the wrapped value, returning an error if the value is currently mutably
+    /// borrowed.
+    ///
+    /// The borrow lasts until the returned `Ref` exits scope. Multiple immutable borrows can be
+    /// taken out at the same time.
+    ///
+    /// This is the non-panicking variant of [`borrow`](#method.borrow).
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(try_borrow)]
+    ///
+    /// use std::cell::RefCell;
+    ///
+    /// let c = RefCell::new(5);
+    ///
+    /// {
+    ///     let m = c.borrow_mut();
+    ///     assert!(c.try_borrow().is_err());
+    /// }
+    ///
+    /// {
+    ///     let m = c.borrow();
+    ///     assert!(c.try_borrow().is_ok());
+    /// }
+    /// ```
+    #[unstable(feature = "try_borrow", issue = "35070")]
+    #[inline]
+    pub fn try_borrow(&self) -> Result<Ref<T>, BorrowError<T>> {
         match BorrowRef::new(&self.borrow) {
-            Some(b) => Ref {
+            Some(b) => Ok(Ref {
                 value: unsafe { &*self.value.get() },
                 borrow: b,
-            },
-            None => panic!("RefCell<T> already mutably borrowed"),
+            }),
+            None => Err(BorrowError { marker: PhantomData }),
         }
     }
 
@@ -479,7 +556,8 @@ pub fn borrow(&self) -> Ref<T> {
     ///
     /// # Panics
     ///
-    /// Panics if the value is currently borrowed.
+    /// Panics if the value is currently borrowed. For a non-panicking variant, use
+    /// [`try_borrow_mut`](#method.try_borrow_mut).
     ///
     /// # Examples
     ///
@@ -511,12 +589,41 @@ pub fn borrow(&self) -> Ref<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn borrow_mut(&self) -> RefMut<T> {
+        self.try_borrow_mut().expect("already borrowed")
+    }
+
+    /// Mutably borrows the wrapped value, returning an error if the value is currently borrowed.
+    ///
+    /// The borrow lasts until the returned `RefMut` exits scope. The value cannot be borrowed
+    /// while this borrow is active.
+    ///
+    /// This is the non-panicking variant of [`borrow_mut`](#method.borrow_mut).
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(try_borrow)]
+    ///
+    /// use std::cell::RefCell;
+    ///
+    /// let c = RefCell::new(5);
+    ///
+    /// {
+    ///     let m = c.borrow();
+    ///     assert!(c.try_borrow_mut().is_err());
+    /// }
+    ///
+    /// assert!(c.try_borrow_mut().is_ok());
+    /// ```
+    #[unstable(feature = "try_borrow", issue = "35070")]
+    #[inline]
+    pub fn try_borrow_mut(&self) -> Result<RefMut<T>, BorrowMutError<T>> {
         match BorrowRefMut::new(&self.borrow) {
-            Some(b) => RefMut {
+            Some(b) => Ok(RefMut {
                 value: unsafe { &mut *self.value.get() },
                 borrow: b,
-            },
-            None => panic!("RefCell<T> already borrowed"),
+            }),
+            None => Err(BorrowMutError { marker: PhantomData }),
         }
     }
 
@@ -847,6 +954,20 @@ impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<RefMut<'b, U>> for RefM
 /// The `UnsafeCell<T>` type is the only legal way to obtain aliasable data that is considered
 /// mutable. In general, transmuting an `&T` type into an `&mut T` is considered undefined behavior.
 ///
+/// The compiler makes optimizations based on the knowledge that `&T` is not mutably aliased or
+/// mutated, and that `&mut T` is unique. When building abstractions like `Cell`, `RefCell`,
+/// `Mutex`, etc, you need to turn these optimizations off. `UnsafeCell` is the only legal way
+/// to do this. When `UnsafeCell<T>` is immutably aliased, it is still safe to obtain a mutable
+/// reference to its interior and/or to mutate it. However, it is up to the abstraction designer
+/// to ensure that no two mutable references obtained this way are active at the same time, and
+/// that there are no active mutable references or mutations when an immutable reference is obtained
+/// from the cell. This is often done via runtime checks.
+///
+/// Note that while mutating or mutably aliasing the contents of an `& UnsafeCell<T>` is
+/// okay (provided you enforce the invariants some other way); it is still undefined behavior
+/// to have multiple `&mut UnsafeCell<T>` aliases.
+///
+///
 /// Types like `Cell<T>` and `RefCell<T>` use this type to wrap their internal data.
 ///
 /// # Examples
@@ -916,6 +1037,11 @@ pub unsafe fn into_inner(self) -> T {
 impl<T: ?Sized> UnsafeCell<T> {
     /// Gets a mutable pointer to the wrapped value.
     ///
+    /// This can be cast to a pointer of any kind.
+    /// Ensure that the access is unique when casting to
+    /// `&mut T`, and ensure that there are no mutations or mutable
+    /// aliases going on when casting to `&T`
+    ///
     /// # Examples
     ///
     /// ```
index 292d72dd362ad5c203497361cd9cda2febfaebc7..4cbabe3f5edafc1036216b05470c7cd7d5478169 100644 (file)
@@ -548,7 +548,7 @@ fn len(&self) -> usize {
     /// assert_eq!(one_element.next(), None);
     /// ```
     #[inline]
-    #[unstable(feature = "exact_size_is_empty", issue = "0")]
+    #[unstable(feature = "exact_size_is_empty", issue = "35428")]
     fn is_empty(&self) -> bool {
         self.len() == 0
     }
index c18d230be31af9db758feb8e6f6de9f439d80ba3..894982abaa939879f58e410e03c595ddf17cb684 100644 (file)
@@ -144,6 +144,12 @@ pub trait Unsize<T: ?Sized> {
 /// Generalizing the latter case, any type implementing `Drop` can't be `Copy`, because it's
 /// managing some resource besides its own `size_of::<T>()` bytes.
 ///
+/// ## What if I derive `Copy` on a type that can't?
+///
+/// If you try to derive `Copy` on a struct or enum, you will get a compile-time error.
+/// Specifically, with structs you'll get [E0204](https://doc.rust-lang.org/error-index.html#E0204)
+/// and with enums you'll get [E0205](https://doc.rust-lang.org/error-index.html#E0205).
+///
 /// ## When should my type be `Copy`?
 ///
 /// Generally speaking, if your type _can_ implement `Copy`, it should. There's one important thing
index 6b2122451db8fbf164190d84d485a09067229113..a7d0d3899b181d2dd3add95f7bbb46c2bb83ced3 100644 (file)
 /// only designed to be used by unsafe code that needs to manipulate
 /// the low-level details.
 ///
-/// There is no `Repr` implementation for `TraitObject` because there
-/// is no way to refer to all trait objects generically, so the only
+/// There is no way to refer to all trait objects generically, so the only
 /// way to create values of this type is with functions like
-/// `std::mem::transmute`. Similarly, the only way to create a true
+/// [`std::mem::transmute`][transmute]. Similarly, the only way to create a true
 /// trait object from a `TraitObject` value is with `transmute`.
 ///
+/// [transmute]: ../intrinsics/fn.transmute.html
+///
 /// Synthesizing a trait object with mismatched types—one where the
 /// vtable does not correspond to the type of the value to which the
 /// data pointer points—is highly likely to lead to undefined
 /// ```
 /// #![feature(raw)]
 ///
-/// use std::mem;
-/// use std::raw;
+/// use std::{mem, raw};
 ///
 /// // an example trait
 /// trait Foo {
 ///     fn bar(&self) -> i32;
 /// }
+///
 /// impl Foo for i32 {
 ///     fn bar(&self) -> i32 {
 ///          *self + 1
@@ -74,7 +75,6 @@
 /// // the data pointer is the address of `value`
 /// assert_eq!(raw_object.data as *const i32, &value as *const _);
 ///
-///
 /// let other_value: i32 = 456;
 ///
 /// // construct a new object, pointing to a different `i32`, being
 /// let synthesized: &Foo = unsafe {
 ///      mem::transmute(raw::TraitObject {
 ///          data: &other_value as *const _ as *mut (),
-///          vtable: raw_object.vtable
+///          vtable: raw_object.vtable,
 ///      })
 /// };
 ///
-/// // it should work just like we constructed a trait object out of
+/// // it should work just as if we had constructed a trait object out of
 /// // `other_value` directly
 /// assert_eq!(synthesized.bar(), 457);
 /// ```
index d8a11581c3b69be0de75868e938add9a8d135a20..3141c289e931ce0b5e001213edec511ca0dbe996 100644 (file)
@@ -105,11 +105,11 @@ fn rsplitn<P>(&self,  n: usize, pred: P) -> RSplitN<Self::Item, P>
     fn binary_search(&self, x: &Self::Item) -> Result<usize, usize>
         where Self::Item: Ord;
     #[stable(feature = "core", since = "1.6.0")]
-    fn binary_search_by<F>(&self, f: F) -> Result<usize, usize>
-        where F: FnMut(&Self::Item) -> Ordering;
+    fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
+        where F: FnMut(&'a Self::Item) -> Ordering;
     #[stable(feature = "slice_binary_search_by_key", since = "1.10.0")]
-    fn binary_search_by_key<B, F>(&self, b: &B, f: F) -> Result<usize, usize>
-        where F: FnMut(&Self::Item) -> B,
+    fn binary_search_by_key<'a, B, F>(&'a self, b: &B, f: F) -> Result<usize, usize>
+        where F: FnMut(&'a Self::Item) -> B,
               B: Ord;
     #[stable(feature = "core", since = "1.6.0")]
     fn len(&self) -> usize;
@@ -301,8 +301,8 @@ fn as_ptr(&self) -> *const T {
         self as *const [T] as *const T
     }
 
-    fn binary_search_by<F>(&self, mut f: F) -> Result<usize, usize> where
-        F: FnMut(&T) -> Ordering
+    fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
+        where F: FnMut(&'a T) -> Ordering
     {
         let mut base = 0usize;
         let mut s = self;
@@ -514,8 +514,8 @@ fn copy_from_slice(&mut self, src: &[T]) where T: Copy {
     }
 
     #[inline]
-    fn binary_search_by_key<B, F>(&self, b: &B, mut f: F) -> Result<usize, usize>
-        where F: FnMut(&Self::Item) -> B,
+    fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
+        where F: FnMut(&'a Self::Item) -> B,
               B: Ord
     {
         self.binary_search_by(|k| f(k).cmp(b))
index 47d9deb62ff6556501c8588981dc621b4282ca1f..2a7a0b62329362b626d01f5d3d78f96a0d471cae 100644 (file)
@@ -74,6 +74,8 @@
 //! ```
 
 #![stable(feature = "rust1", since = "1.0.0")]
+#![cfg_attr(not(target_has_atomic = "8"), allow(dead_code))]
+#![cfg_attr(not(target_has_atomic = "8"), allow(unused_imports))]
 
 use self::Ordering::*;
 
index 9040e4bf8db5f23661174bb68a27822e63aa5d88..74e2c90503cd37fd66477a45e7f024eb485e2480 100644 (file)
@@ -23,7 +23,7 @@
 #[deny(const_err)]
 
 const X: i32 = 42 / 0;
-// error: attempted to divide by zero in a constant expression
+// error: attempt to divide by zero in a constant expression
 ```
 "##,
 
index 20bf4f7d3edbb68dc88517338e2be124937d8642..9212fda6502532e1ab5fc75e466fac752334ad14 100644 (file)
@@ -36,7 +36,7 @@
 use hir::def_id::DefId;
 use util::nodemap::{NodeMap, FnvHashSet};
 
-use syntax_pos::{mk_sp, Span, ExpnId};
+use syntax_pos::{BytePos, mk_sp, Span, ExpnId};
 use syntax::codemap::{self, respan, Spanned};
 use syntax::abi::Abi;
 use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, AsmDialect};
@@ -326,6 +326,38 @@ pub fn is_type_parameterized(&self) -> bool {
     pub fn is_parameterized(&self) -> bool {
         self.is_lt_parameterized() || self.is_type_parameterized()
     }
+
+    // Does return a span which includes lifetimes and type parameters,
+    // not where clause.
+    pub fn span(&self) -> Option<Span> {
+        if !self.is_parameterized() {
+            None
+        } else {
+            let mut span: Option<Span> = None;
+            for lifetime in self.lifetimes.iter() {
+                if let Some(ref mut span) = span {
+                    let life_span = lifetime.lifetime.span;
+                    span.hi = if span.hi > life_span.hi { span.hi } else { life_span.hi };
+                    span.lo = if span.lo < life_span.lo { span.lo } else { life_span.lo };
+                } else {
+                    span = Some(lifetime.lifetime.span.clone());
+                }
+            }
+            for ty_param in self.ty_params.iter() {
+                if let Some(ref mut span) = span {
+                    span.lo = if span.lo < ty_param.span.lo { span.lo } else { ty_param.span.lo };
+                    span.hi = if span.hi > ty_param.span.hi { span.hi } else { ty_param.span.hi };
+                } else {
+                    span = Some(ty_param.span.clone());
+                }
+            }
+            if let Some(ref mut span) = span {
+                span.lo = span.lo - BytePos(1);
+                span.hi = span.hi + BytePos(1);
+            }
+            span
+        }
+    }
 }
 
 /// A `where` clause in a definition
index e856eb84ff2c3a93f33259acb9504d9dcb793fe7..86422835c8cbd0b8d5f1583827eec4503874b17a 100644 (file)
@@ -24,13 +24,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     pub fn prohibit_type_params(self, segments: &[ast::PathSegment]) {
         for segment in segments {
             for typ in segment.parameters.types() {
-                span_err!(self.sess, typ.span, E0109,
-                          "type parameters are not allowed on this type");
+                struct_span_err!(self.sess, typ.span, E0109,
+                                 "type parameters are not allowed on this type")
+                    .span_label(typ.span, &format!("type parameter not allowed"))
+                    .emit();
                 break;
             }
             for lifetime in segment.parameters.lifetimes() {
-                span_err!(self.sess, lifetime.span, E0110,
-                          "lifetime parameters are not allowed on this type");
+                struct_span_err!(self.sess, lifetime.span, E0110,
+                                 "lifetime parameters are not allowed on this type")
+                    .span_label(lifetime.span,
+                                &format!("lifetime parameter not allowed on this type"))
+                    .emit();
                 break;
             }
             for binding in segment.parameters.bindings() {
@@ -42,8 +47,9 @@ pub fn prohibit_type_params(self, segments: &[ast::PathSegment]) {
 
     pub fn prohibit_projection(self, span: Span)
     {
-        span_err!(self.sess, span, E0229,
-                  "associated type bindings are not allowed here");
+        let mut err = struct_span_err!(self.sess, span, E0229,
+                                       "associated type bindings are not allowed here");
+        err.span_label(span, &format!("associate type not allowed here")).emit();
     }
 
     pub fn prim_ty_to_ty(self,
index 23a261400ed076690f3cddaaf93d789e916947eb..0a363fddd53124f6d9cc7218e88d552b94e1469b 100644 (file)
@@ -121,8 +121,11 @@ fn find_item(item: &Item, ctxt: &mut EntryContext, at_root: bool) {
             if ctxt.attr_main_fn.is_none() {
                 ctxt.attr_main_fn = Some((item.id, item.span));
             } else {
-                span_err!(ctxt.session, item.span, E0137,
-                          "multiple functions with a #[main] attribute");
+                struct_span_err!(ctxt.session, item.span, E0137,
+                          "multiple functions with a #[main] attribute")
+                .span_label(item.span, &format!("additional #[main] function"))
+                .span_label(ctxt.attr_main_fn.unwrap().1, &format!("first #[main] function"))
+                .emit();
             }
         },
         EntryPointType::Start => {
index 36268a9de960fcdab041ef8e44b4698332ab8170..cbbc2c4f98f5e09b025f59756289a153805b0f7d 100644 (file)
@@ -19,7 +19,7 @@
 use lint;
 use middle::cstore::LOCAL_CRATE;
 use hir::def::Def;
-use hir::def_id::{CRATE_DEF_INDEX, DefId};
+use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex};
 use ty::{self, TyCtxt};
 use middle::privacy::AccessLevels;
 use syntax::parse::token::InternedString;
@@ -61,12 +61,46 @@ enum AnnotationKind {
     Container,
 }
 
+/// An entry in the `depr_map`.
+#[derive(Clone)]
+pub struct DeprecationEntry {
+    /// The metadata of the attribute associated with this entry.
+    pub attr: Deprecation,
+    /// The def id where the attr was originally attached. `None` for non-local
+    /// `DefId`'s.
+    origin: Option<DefIndex>,
+}
+
+impl DeprecationEntry {
+    fn local(attr: Deprecation, id: DefId) -> DeprecationEntry {
+        assert!(id.is_local());
+        DeprecationEntry {
+            attr: attr,
+            origin: Some(id.index),
+        }
+    }
+
+    fn external(attr: Deprecation) -> DeprecationEntry {
+        DeprecationEntry {
+            attr: attr,
+            origin: None,
+        }
+    }
+
+    pub fn same_origin(&self, other: &DeprecationEntry) -> bool {
+        match (self.origin, other.origin) {
+            (Some(o1), Some(o2)) => o1 == o2,
+            _ => false
+        }
+    }
+}
+
 /// A stability index, giving the stability level for items and methods.
 pub struct Index<'tcx> {
     /// This is mostly a cache, except the stabilities of local items
     /// are filled by the annotator.
     stab_map: DefIdMap<Option<&'tcx Stability>>,
-    depr_map: DefIdMap<Option<Deprecation>>,
+    depr_map: DefIdMap<Option<DeprecationEntry>>,
 
     /// Maps for each crate whether it is part of the staged API.
     staged_api: FnvHashMap<ast::CrateNum, bool>
@@ -77,7 +111,7 @@ struct Annotator<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     index: &'a mut Index<'tcx>,
     parent_stab: Option<&'tcx Stability>,
-    parent_depr: Option<Deprecation>,
+    parent_depr: Option<DeprecationEntry>,
     access_levels: &'a AccessLevels,
     in_trait_impl: bool,
 }
@@ -184,14 +218,15 @@ fn annotate<F>(&mut self, id: NodeId, attrs: &[Attribute],
 
                 // `Deprecation` is just two pointers, no need to intern it
                 let def_id = self.tcx.map.local_def_id(id);
-                self.index.depr_map.insert(def_id, Some(depr.clone()));
+                let depr_entry = Some(DeprecationEntry::local(depr, def_id));
+                self.index.depr_map.insert(def_id, depr_entry.clone());
 
-                let orig_parent_depr = replace(&mut self.parent_depr, Some(depr));
+                let orig_parent_depr = replace(&mut self.parent_depr, depr_entry);
                 visit_children(self);
                 self.parent_depr = orig_parent_depr;
-            } else if let Some(depr) = self.parent_depr.clone() {
+            } else if let parent_depr @ Some(_) = self.parent_depr.clone() {
                 let def_id = self.tcx.map.local_def_id(id);
-                self.index.depr_map.insert(def_id, Some(depr));
+                self.index.depr_map.insert(def_id, parent_depr);
                 visit_children(self);
             } else {
                 visit_children(self);
@@ -351,7 +386,7 @@ struct Checker<'a, 'tcx: 'a> {
 
 impl<'a, 'tcx> Checker<'a, 'tcx> {
     fn check(&mut self, id: DefId, span: Span,
-             stab: &Option<&Stability>, _depr: &Option<Deprecation>) {
+             stab: &Option<&Stability>, _depr: &Option<DeprecationEntry>) {
         if !is_staged_api(self.tcx, id) {
             return;
         }
@@ -476,7 +511,7 @@ pub fn check_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             warn_about_defns: bool,
                             cb: &mut FnMut(DefId, Span,
                                            &Option<&Stability>,
-                                           &Option<Deprecation>)) {
+                                           &Option<DeprecationEntry>)) {
     match item.node {
         hir::ItemExternCrate(_) => {
             // compiler-generated `extern crate` items have a dummy span.
@@ -515,7 +550,7 @@ pub fn check_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 pub fn check_expr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, e: &hir::Expr,
                             cb: &mut FnMut(DefId, Span,
                                            &Option<&Stability>,
-                                           &Option<Deprecation>)) {
+                                           &Option<DeprecationEntry>)) {
     let span;
     let id = match e.node {
         hir::ExprMethodCall(i, _, _) => {
@@ -579,7 +614,7 @@ pub fn check_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             path: &hir::Path, id: ast::NodeId,
                             cb: &mut FnMut(DefId, Span,
                                            &Option<&Stability>,
-                                           &Option<Deprecation>)) {
+                                           &Option<DeprecationEntry>)) {
     // Paths in import prefixes may have no resolution.
     match tcx.expect_def_or_none(id) {
         Some(Def::PrimTy(..)) => {}
@@ -595,7 +630,7 @@ pub fn check_path_list_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                       item: &hir::PathListItem,
                                       cb: &mut FnMut(DefId, Span,
                                                      &Option<&Stability>,
-                                                     &Option<Deprecation>)) {
+                                                     &Option<DeprecationEntry>)) {
     match tcx.expect_def(item.node.id()) {
         Def::PrimTy(..) => {}
         def => {
@@ -607,7 +642,7 @@ pub fn check_path_list_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 pub fn check_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &hir::Pat,
                            cb: &mut FnMut(DefId, Span,
                                           &Option<&Stability>,
-                                          &Option<Deprecation>)) {
+                                          &Option<DeprecationEntry>)) {
     debug!("check_pat(pat = {:?})", pat);
     if is_internal(tcx, pat.span) { return; }
 
@@ -638,7 +673,7 @@ fn maybe_do_stability_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                       id: DefId, span: Span,
                                       cb: &mut FnMut(DefId, Span,
                                                      &Option<&Stability>,
-                                                     &Option<Deprecation>)) {
+                                                     &Option<DeprecationEntry>)) {
     if is_internal(tcx, span) {
         debug!("maybe_do_stability_check: \
                 skipping span={:?} since it is internal", span);
@@ -647,7 +682,7 @@ fn maybe_do_stability_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let (stability, deprecation) = if is_staged_api(tcx, id) {
         (tcx.lookup_stability(id), None)
     } else {
-        (None, tcx.lookup_deprecation(id))
+        (None, tcx.lookup_deprecation_entry(id))
     };
     debug!("maybe_do_stability_check: \
             inspecting id={:?} span={:?} of stability={:?}", id, span, stability);
@@ -685,6 +720,10 @@ pub fn lookup_stability(self, id: DefId) -> Option<&'tcx Stability> {
     }
 
     pub fn lookup_deprecation(self, id: DefId) -> Option<Deprecation> {
+        self.lookup_deprecation_entry(id).map(|depr| depr.attr)
+    }
+
+    pub fn lookup_deprecation_entry(self, id: DefId) -> Option<DeprecationEntry> {
         if let Some(depr) = self.stability.borrow().depr_map.get(&id) {
             return depr.clone();
         }
@@ -703,12 +742,12 @@ fn lookup_stability_uncached(self, id: DefId) -> Option<&'tcx Stability> {
         }
     }
 
-    fn lookup_deprecation_uncached(self, id: DefId) -> Option<Deprecation> {
+    fn lookup_deprecation_uncached(self, id: DefId) -> Option<DeprecationEntry> {
         debug!("lookup(id={:?})", id);
         if id.is_local() {
             None // The stability cache is filled partially lazily
         } else {
-            self.sess.cstore.deprecation(id)
+            self.sess.cstore.deprecation(id).map(DeprecationEntry::external)
         }
     }
 }
index 7543b1d05b1934fdb20d552306f3872e21584b66..20cf9dc44309fa63080a2eacae08ba46379b8c60 100644 (file)
@@ -463,6 +463,8 @@ mod $mod_desc {
         pub const parse_bool: Option<&'static str> = None;
         pub const parse_opt_bool: Option<&'static str> =
             Some("one of: `y`, `yes`, `on`, `n`, `no`, or `off`");
+        pub const parse_all_bool: Option<&'static str> =
+            Some("one of: `y`, `yes`, `on`, `n`, `no`, or `off`");
         pub const parse_string: Option<&'static str> = Some("a string");
         pub const parse_opt_string: Option<&'static str> = Some("a string");
         pub const parse_list: Option<&'static str> = Some("a space-separated list of strings");
@@ -512,6 +514,25 @@ fn parse_opt_bool(slot: &mut Option<bool>, v: Option<&str>) -> bool {
             }
         }
 
+        fn parse_all_bool(slot: &mut bool, v: Option<&str>) -> bool {
+            match v {
+                Some(s) => {
+                    match s {
+                        "n" | "no" | "off" => {
+                            *slot = false;
+                        }
+                        "y" | "yes" | "on" => {
+                            *slot = true;
+                        }
+                        _ => { return false; }
+                    }
+
+                    true
+                },
+                None => { *slot = true; true }
+            }
+        }
+
         fn parse_opt_string(slot: &mut Option<String>, v: Option<&str>) -> bool {
             match v {
                 Some(s) => { *slot = Some(s.to_string()); true },
@@ -758,7 +779,7 @@ fn parse_panic_strategy(slot: &mut PanicStrategy, v: Option<&str>) -> bool {
           "dump MIR state at various points in translation"),
     dump_mir_dir: Option<String> = (None, parse_opt_string,
           "the directory the MIR is dumped into"),
-    orbit: bool = (false, parse_bool,
+    orbit: bool = (true, parse_all_bool,
           "get MIR where it belongs - everywhere; most importantly, in orbit"),
 }
 
@@ -1149,7 +1170,15 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         })
     });
 
-    let debugging_opts = build_debugging_options(matches, error_format);
+    let mut debugging_opts = build_debugging_options(matches, error_format);
+
+    // Incremental compilation only works reliably when translation is done via
+    // MIR, so let's enable -Z orbit if necessary (see #34973).
+    if debugging_opts.incremental.is_some() && !debugging_opts.orbit {
+        early_warn(error_format, "Automatically enabling `-Z orbit` because \
+                                  `-Z incremental` was specified");
+        debugging_opts.orbit = true;
+    }
 
     let parse_only = debugging_opts.parse_only;
     let no_trans = debugging_opts.no_trans;
index 67ad887530eb318ccabe450784dc9480e11e5297..9950560b13a5a7cda70ccd0d38ccc2fedf6a6c46 100644 (file)
@@ -870,10 +870,12 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
 
 
     fn need_type_info(&self, span: Span, ty: Ty<'tcx>) {
-        span_err!(self.tcx.sess, span, E0282,
-                  "unable to infer enough type information about `{}`; \
-                   type annotations or generic parameter binding required",
-                  ty);
+        let mut err = struct_span_err!(self.tcx.sess, span, E0282,
+                                       "unable to infer enough type information about `{}`",
+                                       ty);
+        err.note("type annotations or generic parameter binding required");
+        err.span_label(span, &format!("cannot infer type for `{}`", ty));
+        err.emit()
     }
 
     fn note_obligation_cause<T>(&self,
index ffa1530a14e2644043079ab2690a622020e39ec8..93c6dd09e07b83d2c450f2b97f223b6d8c828b29 100644 (file)
@@ -17,7 +17,6 @@
 //!   - not reference the erased type `Self` except for in this receiver;
 //!   - not have generic type parameters
 
-use super::supertraits;
 use super::elaborate_predicates;
 
 use hir::def_id::DefId;
index fadf36471555b7f83a151bffd55c7c6fa020a915..d9ffe36ea47fbe3610cb927d346cdf4d7a3008d0 100644 (file)
@@ -10,7 +10,6 @@
 
 //! misc. type-system utilities too small to deserve their own file
 
-use hir::svh::Svh;
 use hir::def_id::DefId;
 use ty::subst;
 use infer::InferCtxt;
@@ -18,6 +17,7 @@
 use traits::{self, ProjectionMode};
 use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFlags, TypeFoldable};
 use ty::{Disr, ParameterEnvironment};
+use ty::fold::TypeVisitor;
 use ty::layout::{Layout, LayoutError};
 use ty::TypeVariants::*;
 
@@ -25,6 +25,7 @@
 
 use std::cmp;
 use std::hash::{Hash, SipHasher, Hasher};
+use std::intrinsics;
 use syntax::ast::{self, Name};
 use syntax::attr::{self, SignedInt, UnsignedInt};
 use syntax_pos::Span;
@@ -350,148 +351,13 @@ pub fn required_region_bounds(self,
 
     /// Creates a hash of the type `Ty` which will be the same no matter what crate
     /// context it's calculated within. This is used by the `type_id` intrinsic.
-    pub fn hash_crate_independent(self, ty: Ty<'tcx>, svh: &Svh) -> u64 {
-        let mut state = SipHasher::new();
-        helper(self, ty, svh, &mut state);
-        return state.finish();
-
-        fn helper<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                                  ty: Ty<'tcx>, svh: &Svh,
-                                  state: &mut SipHasher) {
-            macro_rules! byte { ($b:expr) => { ($b as u8).hash(state) } }
-            macro_rules! hash { ($e:expr) => { $e.hash(state) }  }
-
-            let region = |state: &mut SipHasher, r: ty::Region| {
-                match r {
-                    ty::ReStatic | ty::ReErased => {}
-                    ty::ReLateBound(db, ty::BrAnon(i)) => {
-                        db.hash(state);
-                        i.hash(state);
-                    }
-                    ty::ReEmpty |
-                    ty::ReEarlyBound(..) |
-                    ty::ReLateBound(..) |
-                    ty::ReFree(..) |
-                    ty::ReScope(..) |
-                    ty::ReVar(..) |
-                    ty::ReSkolemized(..) => {
-                        bug!("unexpected region found when hashing a type")
-                    }
-                }
-            };
-            let did = |state: &mut SipHasher, did: DefId| {
-                let h = if did.is_local() {
-                    svh.clone()
-                } else {
-                    tcx.sess.cstore.crate_hash(did.krate)
-                };
-                h.hash(state);
-                did.index.hash(state);
-            };
-            let mt = |state: &mut SipHasher, mt: TypeAndMut| {
-                mt.mutbl.hash(state);
-            };
-            let fn_sig = |state: &mut SipHasher, sig: &ty::Binder<ty::FnSig<'tcx>>| {
-                let sig = tcx.anonymize_late_bound_regions(sig).0;
-                for a in &sig.inputs { helper(tcx, *a, svh, state); }
-                if let ty::FnConverging(output) = sig.output {
-                    helper(tcx, output, svh, state);
-                }
-            };
-            ty.maybe_walk(|ty| {
-                match ty.sty {
-                    TyBool => byte!(2),
-                    TyChar => byte!(3),
-                    TyInt(i) => {
-                        byte!(4);
-                        hash!(i);
-                    }
-                    TyUint(u) => {
-                        byte!(5);
-                        hash!(u);
-                    }
-                    TyFloat(f) => {
-                        byte!(6);
-                        hash!(f);
-                    }
-                    TyStr => {
-                        byte!(7);
-                    }
-                    TyEnum(d, _) => {
-                        byte!(8);
-                        did(state, d.did);
-                    }
-                    TyBox(_) => {
-                        byte!(9);
-                    }
-                    TyArray(_, n) => {
-                        byte!(10);
-                        n.hash(state);
-                    }
-                    TySlice(_) => {
-                        byte!(11);
-                    }
-                    TyRawPtr(m) => {
-                        byte!(12);
-                        mt(state, m);
-                    }
-                    TyRef(r, m) => {
-                        byte!(13);
-                        region(state, *r);
-                        mt(state, m);
-                    }
-                    TyFnDef(def_id, _, _) => {
-                        byte!(14);
-                        hash!(def_id);
-                    }
-                    TyFnPtr(ref b) => {
-                        byte!(15);
-                        hash!(b.unsafety);
-                        hash!(b.abi);
-                        fn_sig(state, &b.sig);
-                        return false;
-                    }
-                    TyTrait(ref data) => {
-                        byte!(17);
-                        did(state, data.principal_def_id());
-                        hash!(data.bounds);
-
-                        let principal = tcx.anonymize_late_bound_regions(&data.principal).0;
-                        for subty in &principal.substs.types {
-                            helper(tcx, subty, svh, state);
-                        }
-
-                        return false;
-                    }
-                    TyStruct(d, _) => {
-                        byte!(18);
-                        did(state, d.did);
-                    }
-                    TyTuple(ref inner) => {
-                        byte!(19);
-                        hash!(inner.len());
-                    }
-                    TyParam(p) => {
-                        byte!(20);
-                        hash!(p.space);
-                        hash!(p.idx);
-                        hash!(p.name.as_str());
-                    }
-                    TyInfer(_) => bug!(),
-                    TyError => byte!(21),
-                    TyClosure(d, _) => {
-                        byte!(22);
-                        did(state, d);
-                    }
-                    TyProjection(ref data) => {
-                        byte!(23);
-                        did(state, data.trait_ref.def_id);
-                        hash!(data.item_name.as_str());
-                    }
-                }
-                true
-            });
-        }
+    pub fn type_id_hash(self, ty: Ty<'tcx>) -> u64 {
+        let mut hasher = TypeIdHasher {
+            tcx: self,
+            state: SipHasher::new()
+        };
+        hasher.visit_ty(ty);
+        hasher.state.finish()
     }
 
     /// Returns true if this ADT is a dtorck type.
@@ -525,6 +391,143 @@ pub fn is_adt_dtorck(self, adt: ty::AdtDef) -> bool {
     }
 }
 
+struct TypeIdHasher<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
+    tcx: TyCtxt<'a, 'gcx, 'tcx>,
+    state: SipHasher
+}
+
+impl<'a, 'gcx, 'tcx> TypeIdHasher<'a, 'gcx, 'tcx> {
+    fn hash<T: Hash>(&mut self, x: T) {
+        x.hash(&mut self.state);
+    }
+
+    fn hash_discriminant_u8<T>(&mut self, x: &T) {
+        let v = unsafe {
+            intrinsics::discriminant_value(x)
+        };
+        let b = v as u8;
+        assert_eq!(v, b as u64);
+        self.hash(b)
+    }
+
+    fn def_id(&mut self, did: DefId) {
+        // Hash the crate identification information.
+        let name = self.tcx.crate_name(did.krate);
+        let disambiguator = self.tcx.crate_disambiguator(did.krate);
+        self.hash((name, disambiguator));
+
+        // Hash the item path within that crate.
+        // FIXME(#35379) This should use a deterministic
+        // DefPath hashing mechanism, not the DefIndex.
+        self.hash(did.index);
+    }
+}
+
+impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx> {
+    fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
+        // Distinguish between the Ty variants uniformly.
+        self.hash_discriminant_u8(&ty.sty);
+
+        match ty.sty {
+            TyInt(i) => self.hash(i),
+            TyUint(u) => self.hash(u),
+            TyFloat(f) => self.hash(f),
+            TyStruct(d, _) |
+            TyEnum(d, _) => self.def_id(d.did),
+            TyArray(_, n) => self.hash(n),
+            TyRawPtr(m) |
+            TyRef(_, m) => self.hash(m.mutbl),
+            TyClosure(def_id, _) |
+            TyFnDef(def_id, _, _) => self.def_id(def_id),
+            TyFnPtr(f) => {
+                self.hash(f.unsafety);
+                self.hash(f.abi);
+                self.hash(f.sig.variadic());
+            }
+            TyTrait(ref data) => {
+                // Trait objects have a list of projection bounds
+                // that are not guaranteed to be sorted in an order
+                // that gets preserved across crates, so we need
+                // to sort them again by the name, in string form.
+
+                // Hash the whole principal trait ref.
+                self.def_id(data.principal_def_id());
+                data.principal.visit_with(self);
+
+                // Hash region and builtin bounds.
+                data.bounds.region_bound.visit_with(self);
+                self.hash(data.bounds.builtin_bounds);
+
+                // Only projection bounds are left, sort and hash them.
+                let mut projection_bounds: Vec<_> = data.bounds.projection_bounds
+                                                        .iter()
+                                                        .map(|b| (b.item_name().as_str(), b))
+                                                        .collect();
+                projection_bounds.sort_by_key(|&(ref name, _)| name.clone());
+                for (name, bound) in projection_bounds {
+                    self.def_id(bound.0.projection_ty.trait_ref.def_id);
+                    self.hash(name);
+                    bound.visit_with(self);
+                }
+
+                // Bypass super_visit_with, we've visited everything.
+                return false;
+            }
+            TyTuple(tys) => {
+                self.hash(tys.len());
+            }
+            TyParam(p) => {
+                self.hash(p.space);
+                self.hash(p.idx);
+                self.hash(p.name.as_str());
+            }
+            TyProjection(ref data) => {
+                self.def_id(data.trait_ref.def_id);
+                self.hash(data.item_name.as_str());
+            }
+            TyBool |
+            TyChar |
+            TyStr |
+            TyBox(_) |
+            TySlice(_) |
+            TyError => {}
+            TyInfer(_) => bug!()
+        }
+
+        ty.super_visit_with(self)
+    }
+
+    fn visit_region(&mut self, r: ty::Region) -> bool {
+        match r {
+            ty::ReStatic | ty::ReErased => {
+                self.hash::<u32>(0);
+            }
+            ty::ReLateBound(db, ty::BrAnon(i)) => {
+                assert!(db.depth > 0);
+                self.hash::<u32>(db.depth);
+                self.hash(i);
+            }
+            ty::ReEmpty |
+            ty::ReEarlyBound(..) |
+            ty::ReLateBound(..) |
+            ty::ReFree(..) |
+            ty::ReScope(..) |
+            ty::ReVar(..) |
+            ty::ReSkolemized(..) => {
+                bug!("unexpected region found when hashing a type")
+            }
+        }
+        false
+    }
+
+    fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, x: &ty::Binder<T>) -> bool {
+        // Anonymize late-bound regions so that, for example:
+        // `for<'a, b> fn(&'a &'b T)` and `for<'a, b> fn(&'b &'a T)`
+        // result in the same TypeId (the two types are equivalent).
+        self.tcx.anonymize_late_bound_regions(x).super_visit_with(self)
+    }
+}
+
 impl<'a, 'tcx> ty::TyS<'tcx> {
     fn impls_bound(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                    param_env: &ParameterEnvironment<'tcx>,
index 4b9562ca299fd15327a6574ba364284b91b38f77..904cffac6b3cd88e06b21391382e9f198f3a22b1 100644 (file)
@@ -944,9 +944,12 @@ fn report_out_of_scope_escaping_closure_capture(&self,
                           but it borrows {}, \
                           which is owned by the current function",
                          cmt_path_or_string)
-            .span_note(capture_span,
+            .span_label(capture_span,
                        &format!("{} is borrowed here",
                                 cmt_path_or_string))
+            .span_label(err.span,
+                       &format!("may outlive borrowed value {}",
+                                cmt_path_or_string))
             .span_suggestion(err.span,
                              &format!("to force the closure to take ownership of {} \
                                        (and any other referenced variables), \
index d3952de2fbe30eb1088c6cbaf1df0515d5264419..599e3ec871a8327cdcc08f18083a042806bd7945 100644 (file)
@@ -235,7 +235,12 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &hir::Expr) {
                 .flat_map(|arm| &arm.0)
                 .map(|pat| vec![wrap_pat(cx, &pat)])
                 .collect();
-            check_exhaustive(cx, ex.span, &matrix, source);
+            let match_span = Span {
+                lo: ex.span.lo,
+                hi: scrut.span.hi,
+                expn_id: ex.span.expn_id
+            };
+            check_exhaustive(cx, match_span, &matrix, source);
         },
         _ => ()
     }
@@ -335,6 +340,7 @@ fn check_arms(cx: &MatchCheckCtxt,
                         hir::MatchSource::Normal => {
                             let mut err = struct_span_err!(cx.tcx.sess, pat.span, E0001,
                                                            "unreachable pattern");
+                            err.span_label(pat.span, &format!("this is an unreachable pattern"));
                             // if we had a catchall pattern, hint at that
                             for row in &seen.0 {
                                 if pat_is_catchall(&cx.tcx.def_map.borrow(), row[0].0) {
@@ -423,10 +429,15 @@ fn check_exhaustive<'a, 'tcx>(cx: &MatchCheckCtxt<'a, 'tcx>,
                             format!("`{}` and {} more", head.join("`, `"), tail.len())
                         }
                     };
-                    span_err!(cx.tcx.sess, sp, E0004,
+
+                    let label_text = match pattern_strings.len(){
+                        1 => format!("pattern {} not covered", joined_patterns),
+                        _ => format!("patterns {} not covered", joined_patterns)
+                    };
+                    struct_span_err!(cx.tcx.sess, sp, E0004,
                         "non-exhaustive patterns: {} not covered",
                         joined_patterns
-                    );
+                    ).span_label(sp, &label_text).emit();
                 },
             }
         }
index 45414c33c075448640ef116443fcaf58f23d4e0d..9cdc76f25a63f1a6b77cc446269daa3054b592f7 100644 (file)
@@ -25,8 +25,8 @@
 
 For example, the following `match` block has too many arms:
 
-```compile_fail
-match foo {
+```compile_fail,E0001
+match Some(0) {
     Some(bar) => {/* ... */}
     None => {/* ... */}
     _ => {/* ... */} // All possible cases have already been handled
@@ -108,7 +108,7 @@ fn foo(x: Option<String>) {
 required in order to assign values to match expressions, or alternatively,
 determine the flow of execution. Erroneous code example:
 
-```compile_fail
+```compile_fail,E0004
 enum Terminator {
     HastaLaVistaBaby,
     TalkToMyHand,
@@ -153,7 +153,7 @@ enum Terminator {
 Patterns used to bind names must be irrefutable, that is, they must guarantee
 that a name will be extracted in all cases. Erroneous code example:
 
-```compile_fail
+```compile_fail,E0005
 let x = Some(1);
 let Some(y) = x;
 // error: refutable pattern in local binding: `None` not covered
@@ -187,7 +187,7 @@ enum Terminator {
 moved into a variable called `op_string` while simultaneously requiring the
 inner `String` to be moved into a variable called `s`.
 
-```compile_fail
+```compile_fail,E0007
 let x = Some("s".to_string());
 
 match x {
@@ -205,7 +205,7 @@ enum Terminator {
 referenced in the pattern guard code. Doing so however would prevent the name
 from being available in the body of the match arm. Consider the following:
 
-```compile_fail
+```compile_fail,E0008
 match Some("hi".to_string()) {
     Some(s) if s.len() == 0 => {}, // use s.
     _ => {},
@@ -229,7 +229,7 @@ enum Terminator {
 Though this example seems innocuous and easy to solve, the problem becomes clear
 when it encounters functions which consume the value:
 
-```compile_fail
+```compile_fail,E0008
 struct A{}
 
 impl A {
@@ -283,7 +283,7 @@ fn main() {
 
 Erroneous code example:
 
-```compile_fail
+```compile_fail,E0009
 struct X { x: (), }
 
 let x = Some((X { x: () }, X { x: () }));
@@ -351,25 +351,25 @@ struct X { x: (), }
 match was successful. If the match is irrefutable (when it cannot fail to
 match), use a regular `let`-binding instead. For instance:
 
-```compile_fail
+```compile_fail,E0162
 struct Irrefutable(i32);
 let irr = Irrefutable(0);
 
 // This fails to compile because the match is irrefutable.
 if let Irrefutable(x) = irr {
     // This body will always be executed.
-    foo(x);
+    // ...
 }
 ```
 
 Try this instead:
 
-```ignore
+```
 struct Irrefutable(i32);
 let irr = Irrefutable(0);
 
 let Irrefutable(x) = irr;
-foo(x);
+println!("{}", x);
 ```
 "##,
 
@@ -378,7 +378,7 @@ struct X { x: (), }
 match was successful. If the match is irrefutable (when it cannot fail to
 match), use a regular `let`-binding inside a `loop` instead. For instance:
 
-```compile_fail
+```compile_fail,E0165
 struct Irrefutable(i32);
 let irr = Irrefutable(0);
 
@@ -455,7 +455,7 @@ enum Method { GET, POST }
 loop variable, consider using a `match` or `if let` inside the loop body. For
 instance:
 
-```compile_fail
+```compile_fail,E0297
 let xs : Vec<Option<i32>> = vec!(Some(1), None);
 
 // This fails because `None` is not covered.
@@ -497,7 +497,7 @@ enum Method { GET, POST }
 exhaustive. For instance, the following would not match any arm if mutable
 borrows were allowed:
 
-```compile_fail
+```compile_fail,E0301
 match Some(()) {
     None => { },
     option if option.take().is_none() => {
@@ -515,10 +515,10 @@ enum Method { GET, POST }
 exhaustive. For instance, the following would not match any arm if assignments
 were allowed:
 
-```compile_fail
+```compile_fail,E0302
 match Some(()) {
     None => { },
-    option if { option = None; false } { },
+    option if { option = None; false } => { },
     Some(_) => { } // When the previous match failed, the option became `None`.
 }
 ```
@@ -529,14 +529,18 @@ enum Method { GET, POST }
 Updates to the borrow checker in a future version of Rust may remove this
 restriction, but for now patterns must be rewritten without sub-bindings.
 
-```ignore
-// Before.
+Before:
+
+```compile_fail,E0303
 match Some("hi".to_string()) {
     ref op_string_ref @ Some(s) => {},
     None => {},
 }
+```
+
+After:
 
-// After.
+```
 match Some("hi".to_string()) {
     Some(ref s) => {
         let op_string_ref = &Some(s);
@@ -556,7 +560,7 @@ enum Method { GET, POST }
 constant expression that had to be evaluated. Attempting to divide by 0
 or causing integer overflow are two ways to induce this error. For example:
 
-```compile_fail
+```compile_fail,E0080
 enum Enum {
     X = (1 << 500),
     Y = (1 / 0)
@@ -575,7 +579,7 @@ enum Enum {
 In an array literal `[x; N]`, `N` is the number of elements in the array. This
 must be an unsigned integer. Erroneous code example:
 
-```compile_fail
+```compile_fail,E0306
 let x = [0i32; true]; // error: expected positive integer for repeat count,
                       //        found boolean
 ```
index 227aa7f67688f333d9b1e13d6b12d2fa14ce23c9..ab0f20136eda0dcb4d018dd76e4f11cd38799627 100644 (file)
@@ -1337,10 +1337,13 @@ pub fn eval_length<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             Ok(val as usize)
         },
         Ok(const_val) => {
-            span_err!(tcx.sess, count_expr.span, E0306,
-                      "expected usize for {}, found {}",
-                      reason,
-                      const_val.description());
+            struct_span_err!(tcx.sess, count_expr.span, E0306,
+                             "expected `usize` for {}, found {}",
+                             reason,
+                             const_val.description())
+                .span_label(count_expr.span, &format!("expected `usize`"))
+                .emit();
+
             Err(ErrorReported)
         }
         Err(err) => {
index e4eb0f2c97eb9d5bf77f276155e17804d934ed82..e2e30ef026c2fd81f255071216e819c665633a43 100644 (file)
@@ -57,18 +57,18 @@ pub fn description(&self) -> &'static str {
             UnequalTypes(BitOr) => "tried to bitor two values of different types",
             UnequalTypes(BitXor) => "tried to xor two values of different types",
             UnequalTypes(_) => unreachable!(),
-            Overflow(Add) => "attempted to add with overflow",
-            Overflow(Sub) => "attempted to subtract with overflow",
-            Overflow(Mul) => "attempted to multiply with overflow",
-            Overflow(Div) => "attempted to divide with overflow",
-            Overflow(Rem) => "attempted to calculate the remainder with overflow",
-            Overflow(Neg) => "attempted to negate with overflow",
-            Overflow(Shr) => "attempted to shift right with overflow",
-            Overflow(Shl) => "attempted to shift left with overflow",
+            Overflow(Add) => "attempt to add with overflow",
+            Overflow(Sub) => "attempt to subtract with overflow",
+            Overflow(Mul) => "attempt to multiply with overflow",
+            Overflow(Div) => "attempt to divide with overflow",
+            Overflow(Rem) => "attempt to calculate the remainder with overflow",
+            Overflow(Neg) => "attempt to negate with overflow",
+            Overflow(Shr) => "attempt to shift right with overflow",
+            Overflow(Shl) => "attempt to shift left with overflow",
             Overflow(_) => unreachable!(),
-            ShiftNegative => "attempted to shift by a negative amount",
-            DivisionByZero => "attempted to divide by zero",
-            RemainderByZero => "attempted to calculate the remainder with a divisor of zero",
+            ShiftNegative => "attempt to shift by a negative amount",
+            DivisionByZero => "attempt to divide by zero",
+            RemainderByZero => "attempt to calculate the remainder with a divisor of zero",
             UnsignedNegation => "unary negation of unsigned integer",
             ULitOutOfRange(ast::UintTy::U8) => "literal out of range for u8",
             ULitOutOfRange(ast::UintTy::U16) => "literal out of range for u16",
index f172f38b809686f2995c10639ca4e05945882482..f1f5e194da4d16538418838c23725cad0f45e392 100644 (file)
@@ -995,6 +995,8 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         passes.push_pass(box mir::transform::no_landing_pads::NoLandingPads);
         passes.push_pass(box mir::transform::simplify_cfg::SimplifyCfg::new("elaborate-drops"));
 
+        passes.push_pass(box mir::transform::deaggregator::Deaggregator);
+
         passes.push_pass(box mir::transform::add_call_guards::AddCallGuards);
         passes.push_pass(box mir::transform::dump_mir::Marker("PreTrans"));
 
index f49d47fb0815407827c40bd6bd376d9ed35b5d1c..772c59b34dd02725897eca4d397c6d5bac309aa8 100644 (file)
@@ -186,7 +186,7 @@ macro_rules! do_or_return {($expr: expr, $sess: expr) => {
     let sopts = config::build_session_options(&matches);
 
     if sopts.debugging_opts.debug_llvm {
-        unsafe { llvm::LLVMSetDebug(1); }
+        unsafe { llvm::LLVMRustSetDebug(1); }
     }
 
     let descriptions = diagnostics_registry();
index 7547e28625c18eae079f660280d0950e971728c6..49dad2d0f6d924653de235ab358a5540f163c512 100644 (file)
@@ -567,18 +567,36 @@ fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
 }
 
 /// Checks for use of items with `#[deprecated]` or `#[rustc_deprecated]` attributes
-#[derive(Copy, Clone)]
-pub struct Deprecated;
+#[derive(Clone)]
+pub struct Deprecated {
+    /// Tracks the `NodeId` of the current item.
+    ///
+    /// This is required since not all node ids are present in the hir map.
+    current_item: ast::NodeId,
+}
 
 impl Deprecated {
+    pub fn new() -> Deprecated {
+        Deprecated {
+            current_item: ast::CRATE_NODE_ID,
+        }
+    }
+
     fn lint(&self, cx: &LateContext, _id: DefId, span: Span,
-            stability: &Option<&attr::Stability>, deprecation: &Option<attr::Deprecation>) {
+            stability: &Option<&attr::Stability>,
+            deprecation: &Option<stability::DeprecationEntry>) {
         // Deprecated attributes apply in-crate and cross-crate.
         if let Some(&attr::Stability{rustc_depr: Some(attr::RustcDeprecation{ref reason, ..}), ..})
                 = *stability {
             output(cx, DEPRECATED, span, Some(&reason))
-        } else if let Some(attr::Deprecation{ref note, ..}) = *deprecation {
-            output(cx, DEPRECATED, span, note.as_ref().map(|x| &**x))
+        } else if let Some(ref depr_entry) = *deprecation {
+            if let Some(parent_depr) = cx.tcx.lookup_deprecation_entry(self.parent_def(cx)) {
+                if parent_depr.same_origin(depr_entry) {
+                    return;
+                }
+            }
+
+            output(cx, DEPRECATED, span, depr_entry.attr.note.as_ref().map(|x| &**x))
         }
 
         fn output(cx: &LateContext, lint: &'static Lint, span: Span, note: Option<&str>) {
@@ -591,6 +609,19 @@ fn output(cx: &LateContext, lint: &'static Lint, span: Span, note: Option<&str>)
             cx.span_lint(lint, span, &msg);
         }
     }
+
+    fn push_item(&mut self, item_id: ast::NodeId) {
+        self.current_item = item_id;
+    }
+
+    fn item_post(&mut self, cx: &LateContext, item_id: ast::NodeId) {
+        assert_eq!(self.current_item, item_id);
+        self.current_item = cx.tcx.map.get_parent(item_id);
+    }
+
+    fn parent_def(&self, cx: &LateContext) -> DefId {
+        cx.tcx.map.local_def_id(self.current_item)
+    }
 }
 
 impl LintPass for Deprecated {
@@ -601,11 +632,16 @@ fn get_lints(&self) -> LintArray {
 
 impl LateLintPass for Deprecated {
     fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
+        self.push_item(item.id);
         stability::check_item(cx.tcx, item, false,
                               &mut |id, sp, stab, depr|
                                 self.lint(cx, id, sp, &stab, &depr));
     }
 
+    fn check_item_post(&mut self, cx: &LateContext, item: &hir::Item) {
+        self.item_post(cx, item.id);
+    }
+
     fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
         stability::check_expr(cx.tcx, e,
                               &mut |id, sp, stab, depr|
@@ -629,6 +665,30 @@ fn check_pat(&mut self, cx: &LateContext, pat: &hir::Pat) {
                              &mut |id, sp, stab, depr|
                                 self.lint(cx, id, sp, &stab, &depr));
     }
+
+    fn check_impl_item(&mut self, _: &LateContext, item: &hir::ImplItem) {
+        self.push_item(item.id);
+    }
+
+    fn check_impl_item_post(&mut self, cx: &LateContext, item: &hir::ImplItem) {
+        self.item_post(cx, item.id);
+    }
+
+    fn check_trait_item(&mut self, _: &LateContext, item: &hir::TraitItem) {
+        self.push_item(item.id);
+    }
+
+    fn check_trait_item_post(&mut self, cx: &LateContext, item: &hir::TraitItem) {
+        self.item_post(cx, item.id);
+    }
+
+    fn check_foreign_item(&mut self, _: &LateContext, item: &hir::ForeignItem) {
+        self.push_item(item.id);
+    }
+
+    fn check_foreign_item_post(&mut self, cx: &LateContext, item: &hir::ForeignItem) {
+        self.item_post(cx, item.id);
+    }
 }
 
 declare_lint! {
index 7b0ee91b69ed0848b82a16252df2905469e3976c..43376dfd8c2a0ec6dac298f4ba802f5d4caa84d8 100644 (file)
@@ -124,7 +124,6 @@ macro_rules! add_lint_group {
                  UnusedAllocation,
                  MissingCopyImplementations,
                  UnstableFeatures,
-                 Deprecated,
                  UnconditionalRecursion,
                  InvalidNoMangleItems,
                  PluginAsLibrary,
@@ -133,6 +132,7 @@ macro_rules! add_lint_group {
                  );
 
     add_builtin_with_new!(sess,
+                          Deprecated,
                           TypeLimits,
                           MissingDoc,
                           MissingDebugImplementations,
index 085ea240a5055d3b92b99a721e19e01a24d96d4f..b8548aaec5bd74d023d99016d3042f1c220913aa 100644 (file)
@@ -112,8 +112,7 @@ fn main() {
         cfg.flag(&flag);
     }
 
-    cfg.file("../rustllvm/ExecutionEngineWrapper.cpp")
-       .file("../rustllvm/PassWrapper.cpp")
+    cfg.file("../rustllvm/PassWrapper.cpp")
        .file("../rustllvm/RustWrapper.cpp")
        .file("../rustllvm/ArchiveWrapper.cpp")
        .cpp(true)
index 44e0156146402778af1269c26e9e339a6a7b792e..8520ae1df60dd460898aa08fa6549d2bd23b432a 100644 (file)
 use libc::{c_char, c_uint};
 use std::ptr;
 
-use {DebugLocRef, DiagnosticInfoRef, TwineRef, ValueRef};
+use {DiagnosticInfoRef, TwineRef, ValueRef};
+use ffi::DebugLocRef;
 
 #[derive(Copy, Clone)]
 pub enum OptimizationDiagnosticKind {
     OptimizationRemark,
     OptimizationMissed,
     OptimizationAnalysis,
+    OptimizationAnalysisFPCommute,
+    OptimizationAnalysisAliasing,
     OptimizationFailure,
+    OptimizationRemarkOther,
 }
 
 impl OptimizationDiagnosticKind {
     pub fn describe(self) -> &'static str {
         match self {
-            OptimizationRemark => "remark",
+            OptimizationRemark |
+            OptimizationRemarkOther => "remark",
             OptimizationMissed => "missed",
             OptimizationAnalysis => "analysis",
+            OptimizationAnalysisFPCommute => "floating-point",
+            OptimizationAnalysisAliasing => "aliasing",
             OptimizationFailure => "failure",
         }
     }
@@ -58,11 +65,11 @@ unsafe fn unpack(kind: OptimizationDiagnosticKind,
             message: ptr::null_mut(),
         };
 
-        super::LLVMUnpackOptimizationDiagnostic(di,
-                                                &mut opt.pass_name,
-                                                &mut opt.function,
-                                                &mut opt.debug_loc,
-                                                &mut opt.message);
+        super::LLVMRustUnpackOptimizationDiagnostic(di,
+                                                    &mut opt.pass_name,
+                                                    &mut opt.function,
+                                                    &mut opt.debug_loc,
+                                                    &mut opt.message);
 
         opt
     }
@@ -84,10 +91,10 @@ unsafe fn unpack(di: DiagnosticInfoRef) -> InlineAsmDiagnostic {
             instruction: ptr::null_mut(),
         };
 
-        super::LLVMUnpackInlineAsmDiagnostic(di,
-                                             &mut opt.cookie,
-                                             &mut opt.message,
-                                             &mut opt.instruction);
+        super::LLVMRustUnpackInlineAsmDiagnostic(di,
+                                                 &mut opt.cookie,
+                                                 &mut opt.message,
+                                                 &mut opt.instruction);
 
         opt
     }
@@ -103,24 +110,39 @@ pub enum Diagnostic {
 
 impl Diagnostic {
     pub unsafe fn unpack(di: DiagnosticInfoRef) -> Diagnostic {
-        let kind = super::LLVMGetDiagInfoKind(di);
+        use super::DiagnosticKind as Dk;
+        let kind = super::LLVMRustGetDiagInfoKind(di);
 
         match kind {
-            super::DK_InlineAsm => InlineAsm(InlineAsmDiagnostic::unpack(di)),
+            Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpack(di)),
 
-            super::DK_OptimizationRemark => {
+            Dk::OptimizationRemark => {
                 Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di))
             }
-
-            super::DK_OptimizationRemarkMissed => {
+            Dk::OptimizationRemarkOther => {
+                Optimization(OptimizationDiagnostic::unpack(OptimizationRemarkOther, di))
+            }
+            Dk::OptimizationRemarkMissed => {
                 Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di))
             }
 
-            super::DK_OptimizationRemarkAnalysis => {
+            Dk::OptimizationRemarkAnalysis => {
                 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di))
             }
 
-            super::DK_OptimizationFailure => {
+
+            Dk::OptimizationRemarkAnalysisFPCommute => {
+                Optimization(OptimizationDiagnostic::unpack(
+                    OptimizationAnalysisFPCommute, di))
+            }
+
+            Dk::OptimizationRemarkAnalysisAliasing => {
+                Optimization(OptimizationDiagnostic::unpack(
+                    OptimizationAnalysisAliasing, di))
+            }
+
+
+            Dk::OptimizationFailure => {
                 Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di))
             }
 
diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs
new file mode 100644 (file)
index 0000000..6301c57
--- /dev/null
@@ -0,0 +1,2068 @@
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use debuginfo::{DIBuilderRef, DIDescriptor,
+                DIFile, DILexicalBlock, DISubprogram, DIType,
+                DIBasicType, DIDerivedType, DICompositeType, DIScope,
+                DIVariable, DIGlobalVariable, DIArray, DISubrange,
+                DITemplateTypeParameter, DIEnumerator, DINameSpace};
+
+use libc::{c_uint, c_int, size_t, c_char};
+use libc::{c_longlong, c_ulonglong, c_void};
+
+use RustStringRef;
+
+pub type Opcode = u32;
+pub type Bool = c_uint;
+
+pub const True: Bool = 1 as Bool;
+pub const False: Bool = 0 as Bool;
+
+#[derive(Copy, Clone, PartialEq)]
+#[repr(C)]
+pub enum LLVMRustResult {
+    Success,
+    Failure,
+}
+// Consts for the LLVM CallConv type, pre-cast to usize.
+
+/// LLVM CallingConv::ID. Should we wrap this?
+#[derive(Copy, Clone, PartialEq)]
+#[repr(C)]
+pub enum CallConv {
+    CCallConv = 0,
+    FastCallConv = 8,
+    ColdCallConv = 9,
+    X86StdcallCallConv = 64,
+    X86FastcallCallConv = 65,
+    X86_64_Win64 = 79,
+    X86_VectorCall = 80
+}
+
+/// LLVMLinkage
+///
+/// This enum omits the obsolete (and no-op) linkage types DLLImportLinkage,
+/// DLLExportLinkage, GhostLinkage and LinkOnceODRAutoHideLinkage.
+/// LinkerPrivateLinkage and LinkerPrivateWeakLinkage are not included either;
+/// they've been removed in upstream LLVM commit r203866.
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+#[repr(C)]
+pub enum Linkage {
+    ExternalLinkage = 0,
+    AvailableExternallyLinkage = 1,
+    LinkOnceAnyLinkage = 2,
+    LinkOnceODRLinkage = 3,
+    WeakAnyLinkage = 5,
+    WeakODRLinkage = 6,
+    AppendingLinkage = 7,
+    InternalLinkage = 8,
+    PrivateLinkage = 9,
+    ExternalWeakLinkage = 12,
+    CommonLinkage = 14,
+}
+
+/// LLVMDiagnosticSeverity
+#[derive(Copy, Clone, Debug)]
+#[repr(C)]
+pub enum DiagnosticSeverity {
+    Error = 0,
+    Warning = 1,
+    Remark = 2,
+    Note = 3,
+}
+
+/// LLVMDLLStorageClass
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub enum DLLStorageClass {
+  Default   = 0,
+  DllImport = 1, /* Function to be imported from DLL. */
+  DllExport = 2, /* Function to be accessible from DLL. */
+}
+
+bitflags! {
+    #[derive(Default, Debug)]
+    flags Attribute : u64 {
+        const ZExt            = 1 << 0,
+        const SExt            = 1 << 1,
+        const NoReturn        = 1 << 2,
+        const InReg           = 1 << 3,
+        const StructRet       = 1 << 4,
+        const NoUnwind        = 1 << 5,
+        const NoAlias         = 1 << 6,
+        const ByVal           = 1 << 7,
+        const Nest            = 1 << 8,
+        const ReadNone        = 1 << 9,
+        const ReadOnly        = 1 << 10,
+        const NoInline        = 1 << 11,
+        const AlwaysInline    = 1 << 12,
+        const OptimizeForSize = 1 << 13,
+        const StackProtect    = 1 << 14,
+        const StackProtectReq = 1 << 15,
+        const NoCapture       = 1 << 21,
+        const NoRedZone       = 1 << 22,
+        const NoImplicitFloat = 1 << 23,
+        const Naked           = 1 << 24,
+        const InlineHint      = 1 << 25,
+        const ReturnsTwice    = 1 << 29,
+        const UWTable         = 1 << 30,
+        const NonLazyBind     = 1 << 31,
+
+        // Some of these are missing from the LLVM C API, the rest are
+        // present, but commented out, and preceded by the following warning:
+        // FIXME: These attributes are currently not included in the C API as
+        // a temporary measure until the API/ABI impact to the C API is understood
+        // and the path forward agreed upon.
+        const SanitizeAddress = 1 << 32,
+        const MinSize         = 1 << 33,
+        const NoDuplicate     = 1 << 34,
+        const StackProtectStrong = 1 << 35,
+        const SanitizeThread  = 1 << 36,
+        const SanitizeMemory  = 1 << 37,
+        const NoBuiltin       = 1 << 38,
+        const Returned        = 1 << 39,
+        const Cold            = 1 << 40,
+        const Builtin         = 1 << 41,
+        const OptimizeNone    = 1 << 42,
+        const InAlloca        = 1 << 43,
+        const NonNull         = 1 << 44,
+        const JumpTable       = 1 << 45,
+        const Convergent      = 1 << 46,
+        const SafeStack       = 1 << 47,
+        const NoRecurse       = 1 << 48,
+        const InaccessibleMemOnly         = 1 << 49,
+        const InaccessibleMemOrArgMemOnly = 1 << 50,
+    }
+}
+
+/// LLVMIntPredicate
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub enum IntPredicate {
+    IntEQ = 32,
+    IntNE = 33,
+    IntUGT = 34,
+    IntUGE = 35,
+    IntULT = 36,
+    IntULE = 37,
+    IntSGT = 38,
+    IntSGE = 39,
+    IntSLT = 40,
+    IntSLE = 41,
+}
+
+/// LLVMRealPredicate
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub enum RealPredicate {
+    RealPredicateFalse = 0,
+    RealOEQ = 1,
+    RealOGT = 2,
+    RealOGE = 3,
+    RealOLT = 4,
+    RealOLE = 5,
+    RealONE = 6,
+    RealORD = 7,
+    RealUNO = 8,
+    RealUEQ = 9,
+    RealUGT = 10,
+    RealUGE = 11,
+    RealULT = 12,
+    RealULE = 13,
+    RealUNE = 14,
+    RealPredicateTrue = 15,
+}
+
+/// LLVMTypeKind
+#[derive(Copy, Clone, PartialEq, Debug)]
+#[repr(C)]
+pub enum TypeKind {
+    Void      = 0,
+    Half      = 1,
+    Float     = 2,
+    Double    = 3,
+    X86_FP80  = 4,
+    FP128     = 5,
+    PPC_FP128 = 6,
+    Label     = 7,
+    Integer   = 8,
+    Function  = 9,
+    Struct    = 10,
+    Array     = 11,
+    Pointer   = 12,
+    Vector    = 13,
+    Metadata  = 14,
+    X86_MMX   = 15,
+    Token     = 16,
+}
+
+/// LLVMAtomicRmwBinOp
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub enum AtomicRmwBinOp {
+    AtomicXchg = 0,
+    AtomicAdd  = 1,
+    AtomicSub  = 2,
+    AtomicAnd  = 3,
+    AtomicNand = 4,
+    AtomicOr   = 5,
+    AtomicXor  = 6,
+    AtomicMax  = 7,
+    AtomicMin  = 8,
+    AtomicUMax = 9,
+    AtomicUMin = 10,
+}
+
+/// LLVMAtomicOrdering
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub enum AtomicOrdering {
+    NotAtomic = 0,
+    Unordered = 1,
+    Monotonic = 2,
+    // Consume = 3,  // Not specified yet.
+    Acquire = 4,
+    Release = 5,
+    AcquireRelease = 6,
+    SequentiallyConsistent = 7
+}
+
+/// LLVMRustSynchronizationScope
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub enum SynchronizationScope {
+    Other,
+    SingleThread,
+    CrossThread,
+}
+
+/// LLVMRustFileType
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub enum FileType {
+    Other,
+    AssemblyFile,
+    ObjectFile,
+}
+
+/// Enum pinned in LLVMContext, used in
+/// LLVMSetMetadata so ABI-stable.
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub enum MetadataType {
+    MD_dbg = 0,
+    MD_tbaa = 1,
+    MD_prof = 2,
+    MD_fpmath = 3,
+    MD_range = 4,
+    MD_tbaa_struct = 5,
+    MD_invariant_load = 6,
+    MD_alias_scope = 7,
+    MD_noalias = 8,
+    MD_nontemporal = 9,
+    MD_mem_parallel_loop_access = 10,
+    MD_nonnull = 11,
+}
+
+/// LLVMRustAsmDialect
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub enum AsmDialect {
+    Other,
+    Att,
+    Intel,
+}
+
+/// LLVMRustCodeGenOptLevel
+#[derive(Copy, Clone, PartialEq)]
+#[repr(C)]
+pub enum CodeGenOptLevel {
+    Other,
+    None,
+    Less,
+    Default,
+    Aggressive,
+}
+
+/// LLVMRelocMode
+#[derive(Copy, Clone, PartialEq)]
+#[repr(C)]
+pub enum RelocMode {
+    Default = 0,
+    Static = 1,
+    PIC = 2,
+    DynamicNoPic = 3,
+}
+
+/// LLVMRustCodeModel
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub enum CodeModel {
+    Other,
+    Default,
+    JITDefault,
+    Small,
+    Kernel,
+    Medium,
+    Large,
+}
+
+/// LLVMRustDiagnosticKind
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub enum DiagnosticKind {
+    Other,
+    InlineAsm,
+    StackSize,
+    DebugMetadataVersion,
+    SampleProfile,
+    OptimizationRemark,
+    OptimizationRemarkMissed,
+    OptimizationRemarkAnalysis,
+    OptimizationRemarkAnalysisFPCommute,
+    OptimizationRemarkAnalysisAliasing,
+    OptimizationRemarkOther,
+    OptimizationFailure,
+}
+
+/// LLVMRustArchiveKind
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub enum ArchiveKind {
+    Other,
+    K_GNU,
+    K_MIPS64,
+    K_BSD,
+    K_COFF,
+}
+
+/// LLVMRustPassKind
+#[derive(Copy, Clone, PartialEq, Debug)]
+#[repr(C)]
+pub enum PassKind {
+    Other,
+    Function,
+    Module,
+}
+
+// Opaque pointer types
+#[allow(missing_copy_implementations)]
+pub enum Module_opaque {}
+pub type ModuleRef = *mut Module_opaque;
+#[allow(missing_copy_implementations)]
+pub enum Context_opaque {}
+pub type ContextRef = *mut Context_opaque;
+#[allow(missing_copy_implementations)]
+pub enum Type_opaque {}
+pub type TypeRef = *mut Type_opaque;
+#[allow(missing_copy_implementations)]
+pub enum Value_opaque {}
+pub type ValueRef = *mut Value_opaque;
+#[allow(missing_copy_implementations)]
+pub enum Metadata_opaque {}
+pub type MetadataRef = *mut Metadata_opaque;
+#[allow(missing_copy_implementations)]
+pub enum BasicBlock_opaque {}
+pub type BasicBlockRef = *mut BasicBlock_opaque;
+#[allow(missing_copy_implementations)]
+pub enum Builder_opaque {}
+pub type BuilderRef = *mut Builder_opaque;
+#[allow(missing_copy_implementations)]
+pub enum ExecutionEngine_opaque {}
+pub type ExecutionEngineRef = *mut ExecutionEngine_opaque;
+#[allow(missing_copy_implementations)]
+pub enum MemoryBuffer_opaque {}
+pub type MemoryBufferRef = *mut MemoryBuffer_opaque;
+#[allow(missing_copy_implementations)]
+pub enum PassManager_opaque {}
+pub type PassManagerRef = *mut PassManager_opaque;
+#[allow(missing_copy_implementations)]
+pub enum PassManagerBuilder_opaque {}
+pub type PassManagerBuilderRef = *mut PassManagerBuilder_opaque;
+#[allow(missing_copy_implementations)]
+pub enum Use_opaque {}
+pub type UseRef = *mut Use_opaque;
+#[allow(missing_copy_implementations)]
+pub enum TargetData_opaque {}
+pub type TargetDataRef = *mut TargetData_opaque;
+#[allow(missing_copy_implementations)]
+pub enum ObjectFile_opaque {}
+pub type ObjectFileRef = *mut ObjectFile_opaque;
+#[allow(missing_copy_implementations)]
+pub enum SectionIterator_opaque {}
+pub type SectionIteratorRef = *mut SectionIterator_opaque;
+#[allow(missing_copy_implementations)]
+pub enum Pass_opaque {}
+pub type PassRef = *mut Pass_opaque;
+#[allow(missing_copy_implementations)]
+pub enum TargetMachine_opaque {}
+pub type TargetMachineRef = *mut TargetMachine_opaque;
+pub enum Archive_opaque {}
+pub type ArchiveRef = *mut Archive_opaque;
+pub enum ArchiveIterator_opaque {}
+pub type ArchiveIteratorRef = *mut ArchiveIterator_opaque;
+pub enum ArchiveChild_opaque {}
+pub type ArchiveChildRef = *mut ArchiveChild_opaque;
+#[allow(missing_copy_implementations)]
+pub enum Twine_opaque {}
+pub type TwineRef = *mut Twine_opaque;
+#[allow(missing_copy_implementations)]
+pub enum DiagnosticInfo_opaque {}
+pub type DiagnosticInfoRef = *mut DiagnosticInfo_opaque;
+#[allow(missing_copy_implementations)]
+pub enum DebugLoc_opaque {}
+pub type DebugLocRef = *mut DebugLoc_opaque;
+#[allow(missing_copy_implementations)]
+pub enum SMDiagnostic_opaque {}
+pub type SMDiagnosticRef = *mut SMDiagnostic_opaque;
+#[allow(missing_copy_implementations)]
+pub enum RustArchiveMember_opaque {}
+pub type RustArchiveMemberRef = *mut RustArchiveMember_opaque;
+#[allow(missing_copy_implementations)]
+pub enum OperandBundleDef_opaque {}
+pub type OperandBundleDefRef = *mut OperandBundleDef_opaque;
+
+pub type DiagnosticHandler = unsafe extern "C" fn(DiagnosticInfoRef, *mut c_void);
+pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_void, c_uint);
+
+pub mod debuginfo {
+    pub use self::DIDescriptorFlags::*;
+    use super::{MetadataRef};
+
+    #[allow(missing_copy_implementations)]
+    pub enum DIBuilder_opaque {}
+    pub type DIBuilderRef = *mut DIBuilder_opaque;
+
+    pub type DIDescriptor = MetadataRef;
+    pub type DIScope = DIDescriptor;
+    pub type DILocation = DIDescriptor;
+    pub type DIFile = DIScope;
+    pub type DILexicalBlock = DIScope;
+    pub type DISubprogram = DIScope;
+    pub type DINameSpace = DIScope;
+    pub type DIType = DIDescriptor;
+    pub type DIBasicType = DIType;
+    pub type DIDerivedType = DIType;
+    pub type DICompositeType = DIDerivedType;
+    pub type DIVariable = DIDescriptor;
+    pub type DIGlobalVariable = DIDescriptor;
+    pub type DIArray = DIDescriptor;
+    pub type DISubrange = DIDescriptor;
+    pub type DIEnumerator = DIDescriptor;
+    pub type DITemplateTypeParameter = DIDescriptor;
+
+    #[derive(Copy, Clone)]
+    pub enum DIDescriptorFlags {
+      FlagPrivate            = 1 << 0,
+      FlagProtected          = 1 << 1,
+      FlagFwdDecl            = 1 << 2,
+      FlagAppleBlock         = 1 << 3,
+      FlagBlockByrefStruct   = 1 << 4,
+      FlagVirtual            = 1 << 5,
+      FlagArtificial         = 1 << 6,
+      FlagExplicit           = 1 << 7,
+      FlagPrototyped         = 1 << 8,
+      FlagObjcClassComplete  = 1 << 9,
+      FlagObjectPointer      = 1 << 10,
+      FlagVector             = 1 << 11,
+      FlagStaticMember       = 1 << 12,
+      FlagIndirectVariable   = 1 << 13,
+      FlagLValueReference    = 1 << 14,
+      FlagRValueReference    = 1 << 15
+    }
+}
+
+
+// Link to our native llvm bindings (things that we need to use the C++ api
+// for) and because llvm is written in C++ we need to link against libstdc++
+//
+// You'll probably notice that there is an omission of all LLVM libraries
+// from this location. This is because the set of LLVM libraries that we
+// link to is mostly defined by LLVM, and the `llvm-config` tool is used to
+// figure out the exact set of libraries. To do this, the build system
+// generates an llvmdeps.rs file next to this one which will be
+// automatically updated whenever LLVM is updated to include an up-to-date
+// set of the libraries we need to link to LLVM for.
+#[link(name = "rustllvm", kind = "static")]
+#[cfg(not(cargobuild))]
+extern {}
+
+#[linked_from = "rustllvm"] // not quite true but good enough
+extern {
+    /* Create and destroy contexts. */
+    pub fn LLVMContextCreate() -> ContextRef;
+    pub fn LLVMContextDispose(C: ContextRef);
+    pub fn LLVMGetMDKindIDInContext(C: ContextRef,
+                                    Name: *const c_char,
+                                    SLen: c_uint)
+                                    -> c_uint;
+
+    /* Create and destroy modules. */
+    pub fn LLVMModuleCreateWithNameInContext(ModuleID: *const c_char,
+                                             C: ContextRef)
+                                             -> ModuleRef;
+    pub fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef;
+    pub fn LLVMCloneModule(M: ModuleRef) -> ModuleRef;
+    pub fn LLVMDisposeModule(M: ModuleRef);
+
+    /// Data layout. See Module::getDataLayout.
+    pub fn LLVMGetDataLayout(M: ModuleRef) -> *const c_char;
+    pub fn LLVMSetDataLayout(M: ModuleRef, Triple: *const c_char);
+
+    /// Target triple. See Module::getTargetTriple.
+    pub fn LLVMGetTarget(M: ModuleRef) -> *const c_char;
+    pub fn LLVMSetTarget(M: ModuleRef, Triple: *const c_char);
+
+    /// See Module::dump.
+    pub fn LLVMDumpModule(M: ModuleRef);
+
+    /// See Module::setModuleInlineAsm.
+    pub fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *const c_char);
+
+    /// See llvm::LLVMTypeKind::getTypeID.
+    pub fn LLVMRustGetTypeKind(Ty: TypeRef) -> TypeKind;
+
+    /// See llvm::LLVMType::getContext.
+    pub fn LLVMGetTypeContext(Ty: TypeRef) -> ContextRef;
+
+    /* Operations on integer types */
+    pub fn LLVMInt1TypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMInt8TypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMInt16TypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMInt32TypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMInt64TypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMIntTypeInContext(C: ContextRef, NumBits: c_uint)
+                                -> TypeRef;
+
+    pub fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint;
+
+    /* Operations on real types */
+    pub fn LLVMFloatTypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMDoubleTypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMX86FP80TypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMFP128TypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMPPCFP128TypeInContext(C: ContextRef) -> TypeRef;
+
+    /* Operations on function types */
+    pub fn LLVMFunctionType(ReturnType: TypeRef,
+                            ParamTypes: *const TypeRef,
+                            ParamCount: c_uint,
+                            IsVarArg: Bool)
+                            -> TypeRef;
+    pub fn LLVMIsFunctionVarArg(FunctionTy: TypeRef) -> Bool;
+    pub fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef;
+    pub fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint;
+    pub fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *mut TypeRef);
+
+    /* Operations on struct types */
+    pub fn LLVMStructTypeInContext(C: ContextRef,
+                                   ElementTypes: *const TypeRef,
+                                   ElementCount: c_uint,
+                                   Packed: Bool)
+                                   -> TypeRef;
+    pub fn LLVMCountStructElementTypes(StructTy: TypeRef) -> c_uint;
+    pub fn LLVMGetStructElementTypes(StructTy: TypeRef,
+                                     Dest: *mut TypeRef);
+    pub fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool;
+
+    /* Operations on array, pointer, and vector types (sequence types) */
+    pub fn LLVMRustArrayType(ElementType: TypeRef, ElementCount: u64) -> TypeRef;
+    pub fn LLVMPointerType(ElementType: TypeRef, AddressSpace: c_uint)
+                           -> TypeRef;
+    pub fn LLVMVectorType(ElementType: TypeRef, ElementCount: c_uint)
+                          -> TypeRef;
+
+    pub fn LLVMGetElementType(Ty: TypeRef) -> TypeRef;
+    pub fn LLVMGetArrayLength(ArrayTy: TypeRef) -> c_uint;
+    pub fn LLVMGetPointerAddressSpace(PointerTy: TypeRef) -> c_uint;
+    pub fn LLVMGetPointerToGlobal(EE: ExecutionEngineRef, V: ValueRef)
+                                  -> *const c_void;
+    pub fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint;
+
+    /* Operations on other types */
+    pub fn LLVMVoidTypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMLabelTypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMRustMetadataTypeInContext(C: ContextRef) -> TypeRef;
+
+    /* Operations on all values */
+    pub fn LLVMTypeOf(Val: ValueRef) -> TypeRef;
+    pub fn LLVMGetValueName(Val: ValueRef) -> *const c_char;
+    pub fn LLVMSetValueName(Val: ValueRef, Name: *const c_char);
+    pub fn LLVMDumpValue(Val: ValueRef);
+    pub fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef);
+    pub fn LLVMSetMetadata(Val: ValueRef, KindID: c_uint, Node: ValueRef);
+
+    /* Operations on Uses */
+    pub fn LLVMGetFirstUse(Val: ValueRef) -> UseRef;
+    pub fn LLVMGetNextUse(U: UseRef) -> UseRef;
+    pub fn LLVMGetUser(U: UseRef) -> ValueRef;
+    pub fn LLVMGetUsedValue(U: UseRef) -> ValueRef;
+
+    /* Operations on Users */
+    pub fn LLVMGetNumOperands(Val: ValueRef) -> c_int;
+    pub fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
+    pub fn LLVMSetOperand(Val: ValueRef, Index: c_uint, Op: ValueRef);
+
+    /* Operations on constants of any type */
+    pub fn LLVMConstNull(Ty: TypeRef) -> ValueRef;
+    /* all zeroes */
+    pub fn LLVMConstAllOnes(Ty: TypeRef) -> ValueRef;
+    pub fn LLVMConstICmp(Pred: IntPredicate, V1: ValueRef, V2: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef)
+                         -> ValueRef;
+    /* only for isize/vector */
+    pub fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;
+    pub fn LLVMIsConstant(Val: ValueRef) -> Bool;
+    pub fn LLVMIsNull(Val: ValueRef) -> Bool;
+    pub fn LLVMIsUndef(Val: ValueRef) -> Bool;
+    pub fn LLVMConstPointerNull(Ty: TypeRef) -> ValueRef;
+
+    /* Operations on metadata */
+    pub fn LLVMMDStringInContext(C: ContextRef,
+                                 Str: *const c_char,
+                                 SLen: c_uint)
+                                 -> ValueRef;
+    pub fn LLVMMDNodeInContext(C: ContextRef,
+                               Vals: *const ValueRef,
+                               Count: c_uint)
+                               -> ValueRef;
+    pub fn LLVMAddNamedMetadataOperand(M: ModuleRef,
+                                       Str: *const c_char,
+                                       Val: ValueRef);
+
+    /* Operations on scalar constants */
+    pub fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool)
+                        -> ValueRef;
+    pub fn LLVMConstIntOfString(IntTy: TypeRef, Text: *const c_char, Radix: u8)
+                                -> ValueRef;
+    pub fn LLVMConstIntOfStringAndSize(IntTy: TypeRef,
+                                       Text: *const c_char,
+                                       SLen: c_uint,
+                                       Radix: u8)
+                                       -> ValueRef;
+    pub fn LLVMConstReal(RealTy: TypeRef, N: f64) -> ValueRef;
+    pub fn LLVMConstRealOfString(RealTy: TypeRef, Text: *const c_char)
+                                 -> ValueRef;
+    pub fn LLVMConstRealOfStringAndSize(RealTy: TypeRef,
+                                        Text: *const c_char,
+                                        SLen: c_uint)
+                                        -> ValueRef;
+    pub fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
+    pub fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
+
+
+    /* Operations on composite constants */
+    pub fn LLVMConstStringInContext(C: ContextRef,
+                                    Str: *const c_char,
+                                    Length: c_uint,
+                                    DontNullTerminate: Bool)
+                                    -> ValueRef;
+    pub fn LLVMConstStructInContext(C: ContextRef,
+                                    ConstantVals: *const ValueRef,
+                                    Count: c_uint,
+                                    Packed: Bool)
+                                    -> ValueRef;
+
+    pub fn LLVMConstArray(ElementTy: TypeRef,
+                          ConstantVals: *const ValueRef,
+                          Length: c_uint)
+                          -> ValueRef;
+    pub fn LLVMConstVector(ScalarConstantVals: *const ValueRef, Size: c_uint)
+                           -> ValueRef;
+
+    /* Constant expressions */
+    pub fn LLVMAlignOf(Ty: TypeRef) -> ValueRef;
+    pub fn LLVMSizeOf(Ty: TypeRef) -> ValueRef;
+    pub fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef;
+    pub fn LLVMConstNSWNeg(ConstantVal: ValueRef) -> ValueRef;
+    pub fn LLVMConstNUWNeg(ConstantVal: ValueRef) -> ValueRef;
+    pub fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef;
+    pub fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef;
+    pub fn LLVMConstAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                        -> ValueRef;
+    pub fn LLVMConstNSWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                           -> ValueRef;
+    pub fn LLVMConstNUWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                           -> ValueRef;
+    pub fn LLVMConstFAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                        -> ValueRef;
+    pub fn LLVMConstNSWSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                           -> ValueRef;
+    pub fn LLVMConstNUWSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                           -> ValueRef;
+    pub fn LLVMConstFSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                        -> ValueRef;
+    pub fn LLVMConstNSWMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                           -> ValueRef;
+    pub fn LLVMConstNUWMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                           -> ValueRef;
+    pub fn LLVMConstFMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstUDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstSDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstExactSDiv(LHSConstant: ValueRef,
+                              RHSConstant: ValueRef)
+                              -> ValueRef;
+    pub fn LLVMConstFDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstURem(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstSRem(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstFRem(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstAnd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                        -> ValueRef;
+    pub fn LLVMConstOr(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                       -> ValueRef;
+    pub fn LLVMConstXor(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                        -> ValueRef;
+    pub fn LLVMConstShl(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                        -> ValueRef;
+    pub fn LLVMConstLShr(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstAShr(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstGEP(ConstantVal: ValueRef,
+                        ConstantIndices: *const ValueRef,
+                        NumIndices: c_uint)
+                        -> ValueRef;
+    pub fn LLVMConstInBoundsGEP(ConstantVal: ValueRef,
+                                ConstantIndices: *const ValueRef,
+                                NumIndices: c_uint)
+                                -> ValueRef;
+    pub fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: TypeRef)
+                          -> ValueRef;
+    pub fn LLVMConstSExt(ConstantVal: ValueRef, ToType: TypeRef)
+                         -> ValueRef;
+    pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: TypeRef)
+                         -> ValueRef;
+    pub fn LLVMConstFPTrunc(ConstantVal: ValueRef, ToType: TypeRef)
+                            -> ValueRef;
+    pub fn LLVMConstFPExt(ConstantVal: ValueRef, ToType: TypeRef)
+                          -> ValueRef;
+    pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: TypeRef)
+                           -> ValueRef;
+    pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: TypeRef)
+                           -> ValueRef;
+    pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: TypeRef)
+                           -> ValueRef;
+    pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: TypeRef)
+                           -> ValueRef;
+    pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: TypeRef)
+                             -> ValueRef;
+    pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: TypeRef)
+                             -> ValueRef;
+    pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: TypeRef)
+                            -> ValueRef;
+    pub fn LLVMConstZExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
+                                  -> ValueRef;
+    pub fn LLVMConstSExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
+                                  -> ValueRef;
+    pub fn LLVMConstTruncOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
+                                   -> ValueRef;
+    pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: TypeRef)
+                                -> ValueRef;
+    pub fn LLVMConstIntCast(ConstantVal: ValueRef,
+                            ToType: TypeRef,
+                            isSigned: Bool)
+                            -> ValueRef;
+    pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: TypeRef)
+                           -> ValueRef;
+    pub fn LLVMConstSelect(ConstantCondition: ValueRef,
+                           ConstantIfTrue: ValueRef,
+                           ConstantIfFalse: ValueRef)
+                           -> ValueRef;
+    pub fn LLVMConstExtractElement(VectorConstant: ValueRef,
+                                   IndexConstant: ValueRef)
+                                   -> ValueRef;
+    pub fn LLVMConstInsertElement(VectorConstant: ValueRef,
+                                  ElementValueConstant: ValueRef,
+                                  IndexConstant: ValueRef)
+                                  -> ValueRef;
+    pub fn LLVMConstShuffleVector(VectorAConstant: ValueRef,
+                                  VectorBConstant: ValueRef,
+                                  MaskConstant: ValueRef)
+                                  -> ValueRef;
+    pub fn LLVMConstExtractValue(AggConstant: ValueRef,
+                                 IdxList: *const c_uint,
+                                 NumIdx: c_uint)
+                                 -> ValueRef;
+    pub fn LLVMConstInsertValue(AggConstant: ValueRef,
+                                ElementValueConstant: ValueRef,
+                                IdxList: *const c_uint,
+                                NumIdx: c_uint)
+                                -> ValueRef;
+    pub fn LLVMConstInlineAsm(Ty: TypeRef,
+                              AsmString: *const c_char,
+                              Constraints: *const c_char,
+                              HasSideEffects: Bool,
+                              IsAlignStack: Bool)
+                              -> ValueRef;
+    pub fn LLVMBlockAddress(F: ValueRef, BB: BasicBlockRef) -> ValueRef;
+
+
+
+    /* Operations on global variables, functions, and aliases (globals) */
+    pub fn LLVMGetGlobalParent(Global: ValueRef) -> ModuleRef;
+    pub fn LLVMIsDeclaration(Global: ValueRef) -> Bool;
+    pub fn LLVMGetLinkage(Global: ValueRef) -> c_uint;
+    pub fn LLVMSetLinkage(Global: ValueRef, Link: Linkage);
+    pub fn LLVMGetSection(Global: ValueRef) -> *const c_char;
+    pub fn LLVMSetSection(Global: ValueRef, Section: *const c_char);
+    pub fn LLVMGetVisibility(Global: ValueRef) -> c_uint;
+    pub fn LLVMSetVisibility(Global: ValueRef, Viz: c_uint);
+    pub fn LLVMGetAlignment(Global: ValueRef) -> c_uint;
+    pub fn LLVMSetAlignment(Global: ValueRef, Bytes: c_uint);
+    pub fn LLVMSetDLLStorageClass(V: ValueRef,
+                                  C: DLLStorageClass);
+
+
+    /* Operations on global variables */
+    pub fn LLVMIsAGlobalVariable(GlobalVar: ValueRef) -> ValueRef;
+    pub fn LLVMAddGlobal(M: ModuleRef, Ty: TypeRef, Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMAddGlobalInAddressSpace(M: ModuleRef,
+                                       Ty: TypeRef,
+                                       Name: *const c_char,
+                                       AddressSpace: c_uint)
+                                       -> ValueRef;
+    pub fn LLVMGetNamedGlobal(M: ModuleRef,
+                              Name: *const c_char)
+                              -> ValueRef;
+    pub fn LLVMRustGetOrInsertGlobal(M: ModuleRef,
+                                     Name: *const c_char,
+                                     T: TypeRef)
+                                     -> ValueRef;
+    pub fn LLVMGetFirstGlobal(M: ModuleRef) -> ValueRef;
+    pub fn LLVMGetLastGlobal(M: ModuleRef) -> ValueRef;
+    pub fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef;
+    pub fn LLVMGetPreviousGlobal(GlobalVar: ValueRef) -> ValueRef;
+    pub fn LLVMDeleteGlobal(GlobalVar: ValueRef);
+    pub fn LLVMGetInitializer(GlobalVar: ValueRef) -> ValueRef;
+    pub fn LLVMSetInitializer(GlobalVar: ValueRef,
+                              ConstantVal: ValueRef);
+    pub fn LLVMIsThreadLocal(GlobalVar: ValueRef) -> Bool;
+    pub fn LLVMSetThreadLocal(GlobalVar: ValueRef, IsThreadLocal: Bool);
+    pub fn LLVMIsGlobalConstant(GlobalVar: ValueRef) -> Bool;
+    pub fn LLVMSetGlobalConstant(GlobalVar: ValueRef, IsConstant: Bool);
+    pub fn LLVMRustGetNamedValue(M: ModuleRef, Name: *const c_char) -> ValueRef;
+
+    /* Operations on aliases */
+    pub fn LLVMAddAlias(M: ModuleRef,
+                        Ty: TypeRef,
+                        Aliasee: ValueRef,
+                        Name: *const c_char)
+                        -> ValueRef;
+
+    /* Operations on functions */
+    pub fn LLVMAddFunction(M: ModuleRef,
+                           Name: *const c_char,
+                           FunctionTy: TypeRef)
+                           -> ValueRef;
+    pub fn LLVMGetNamedFunction(M: ModuleRef, Name: *const c_char) -> ValueRef;
+    pub fn LLVMGetFirstFunction(M: ModuleRef) -> ValueRef;
+    pub fn LLVMGetLastFunction(M: ModuleRef) -> ValueRef;
+    pub fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef;
+    pub fn LLVMGetPreviousFunction(Fn: ValueRef) -> ValueRef;
+    pub fn LLVMDeleteFunction(Fn: ValueRef);
+    pub fn LLVMRustGetOrInsertFunction(M: ModuleRef,
+                                       Name: *const c_char,
+                                       FunctionTy: TypeRef)
+                                       -> ValueRef;
+    pub fn LLVMGetIntrinsicID(Fn: ValueRef) -> c_uint;
+    pub fn LLVMGetFunctionCallConv(Fn: ValueRef) -> c_uint;
+    pub fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
+    pub fn LLVMGetGC(Fn: ValueRef) -> *const c_char;
+    pub fn LLVMSetGC(Fn: ValueRef, Name: *const c_char);
+    pub fn LLVMRustAddDereferenceableAttr(Fn: ValueRef, index: c_uint, bytes: u64);
+    pub fn LLVMRustAddFunctionAttribute(Fn: ValueRef, index: c_uint, PA: u64);
+    pub fn LLVMRustAddFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
+    pub fn LLVMRustAddFunctionAttrStringValue(Fn: ValueRef, index: c_uint,
+                                              Name: *const c_char,
+                                              Value: *const c_char);
+    pub fn LLVMRustRemoveFunctionAttributes(Fn: ValueRef,
+                                            index: c_uint,
+                                            attr: u64);
+    pub fn LLVMRustRemoveFunctionAttrString(Fn: ValueRef,
+                                            index: c_uint,
+                                            Name: *const c_char);
+    pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_uint;
+    pub fn LLVMRemoveFunctionAttr(Fn: ValueRef, val: c_uint);
+
+    /* Operations on parameters */
+    pub fn LLVMCountParams(Fn: ValueRef) -> c_uint;
+    pub fn LLVMGetParams(Fn: ValueRef, Params: *const ValueRef);
+    pub fn LLVMGetParam(Fn: ValueRef, Index: c_uint) -> ValueRef;
+    pub fn LLVMGetParamParent(Inst: ValueRef) -> ValueRef;
+    pub fn LLVMGetFirstParam(Fn: ValueRef) -> ValueRef;
+    pub fn LLVMGetLastParam(Fn: ValueRef) -> ValueRef;
+    pub fn LLVMGetNextParam(Arg: ValueRef) -> ValueRef;
+    pub fn LLVMGetPreviousParam(Arg: ValueRef) -> ValueRef;
+    pub fn LLVMAddAttribute(Arg: ValueRef, PA: c_uint);
+    pub fn LLVMRemoveAttribute(Arg: ValueRef, PA: c_uint);
+    pub fn LLVMGetAttribute(Arg: ValueRef) -> c_uint;
+    pub fn LLVMSetParamAlignment(Arg: ValueRef, align: c_uint);
+
+    /* Operations on basic blocks */
+    pub fn LLVMBasicBlockAsValue(BB: BasicBlockRef) -> ValueRef;
+    pub fn LLVMValueIsBasicBlock(Val: ValueRef) -> Bool;
+    pub fn LLVMValueAsBasicBlock(Val: ValueRef) -> BasicBlockRef;
+    pub fn LLVMGetBasicBlockParent(BB: BasicBlockRef) -> ValueRef;
+    pub fn LLVMCountBasicBlocks(Fn: ValueRef) -> c_uint;
+    pub fn LLVMGetBasicBlocks(Fn: ValueRef, BasicBlocks: *const ValueRef);
+    pub fn LLVMGetFirstBasicBlock(Fn: ValueRef) -> BasicBlockRef;
+    pub fn LLVMGetLastBasicBlock(Fn: ValueRef) -> BasicBlockRef;
+    pub fn LLVMGetNextBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
+    pub fn LLVMGetPreviousBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
+    pub fn LLVMGetEntryBasicBlock(Fn: ValueRef) -> BasicBlockRef;
+
+    pub fn LLVMAppendBasicBlockInContext(C: ContextRef,
+                                         Fn: ValueRef,
+                                         Name: *const c_char)
+                                         -> BasicBlockRef;
+    pub fn LLVMInsertBasicBlockInContext(C: ContextRef,
+                                         BB: BasicBlockRef,
+                                         Name: *const c_char)
+                                         -> BasicBlockRef;
+    pub fn LLVMDeleteBasicBlock(BB: BasicBlockRef);
+
+    pub fn LLVMMoveBasicBlockAfter(BB: BasicBlockRef,
+                                   MoveAfter: BasicBlockRef);
+
+    pub fn LLVMMoveBasicBlockBefore(BB: BasicBlockRef,
+                                    MoveBefore: BasicBlockRef);
+
+    /* Operations on instructions */
+    pub fn LLVMGetInstructionParent(Inst: ValueRef) -> BasicBlockRef;
+    pub fn LLVMGetFirstInstruction(BB: BasicBlockRef) -> ValueRef;
+    pub fn LLVMGetLastInstruction(BB: BasicBlockRef) -> ValueRef;
+    pub fn LLVMGetNextInstruction(Inst: ValueRef) -> ValueRef;
+    pub fn LLVMGetPreviousInstruction(Inst: ValueRef) -> ValueRef;
+    pub fn LLVMInstructionEraseFromParent(Inst: ValueRef);
+
+    /* Operations on call sites */
+    pub fn LLVMSetInstructionCallConv(Instr: ValueRef, CC: c_uint);
+    pub fn LLVMGetInstructionCallConv(Instr: ValueRef) -> c_uint;
+    pub fn LLVMAddInstrAttribute(Instr: ValueRef,
+                                 index: c_uint,
+                                 IA: c_uint);
+    pub fn LLVMRemoveInstrAttribute(Instr: ValueRef,
+                                    index: c_uint,
+                                    IA: c_uint);
+    pub fn LLVMSetInstrParamAlignment(Instr: ValueRef,
+                                      index: c_uint,
+                                      align: c_uint);
+    pub fn LLVMRustAddCallSiteAttribute(Instr: ValueRef,
+                                    index: c_uint,
+                                    Val: u64);
+    pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: ValueRef,
+                                                  index: c_uint,
+                                                  bytes: u64);
+
+    /* Operations on call instructions (only) */
+    pub fn LLVMIsTailCall(CallInst: ValueRef) -> Bool;
+    pub fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool);
+
+    /* Operations on load/store instructions (only) */
+    pub fn LLVMGetVolatile(MemoryAccessInst: ValueRef) -> Bool;
+    pub fn LLVMSetVolatile(MemoryAccessInst: ValueRef, volatile: Bool);
+
+    /* Operations on phi nodes */
+    pub fn LLVMAddIncoming(PhiNode: ValueRef,
+                           IncomingValues: *const ValueRef,
+                           IncomingBlocks: *const BasicBlockRef,
+                           Count: c_uint);
+    pub fn LLVMCountIncoming(PhiNode: ValueRef) -> c_uint;
+    pub fn LLVMGetIncomingValue(PhiNode: ValueRef, Index: c_uint)
+                                -> ValueRef;
+    pub fn LLVMGetIncomingBlock(PhiNode: ValueRef, Index: c_uint)
+                                -> BasicBlockRef;
+
+    /* Instruction builders */
+    pub fn LLVMCreateBuilderInContext(C: ContextRef) -> BuilderRef;
+    pub fn LLVMPositionBuilder(Builder: BuilderRef,
+                               Block: BasicBlockRef,
+                               Instr: ValueRef);
+    pub fn LLVMPositionBuilderBefore(Builder: BuilderRef,
+                                     Instr: ValueRef);
+    pub fn LLVMPositionBuilderAtEnd(Builder: BuilderRef,
+                                    Block: BasicBlockRef);
+    pub fn LLVMGetInsertBlock(Builder: BuilderRef) -> BasicBlockRef;
+    pub fn LLVMClearInsertionPosition(Builder: BuilderRef);
+    pub fn LLVMInsertIntoBuilder(Builder: BuilderRef, Instr: ValueRef);
+    pub fn LLVMInsertIntoBuilderWithName(Builder: BuilderRef,
+                                         Instr: ValueRef,
+                                         Name: *const c_char);
+    pub fn LLVMDisposeBuilder(Builder: BuilderRef);
+
+    /* Metadata */
+    pub fn LLVMSetCurrentDebugLocation(Builder: BuilderRef, L: ValueRef);
+    pub fn LLVMGetCurrentDebugLocation(Builder: BuilderRef) -> ValueRef;
+    pub fn LLVMSetInstDebugLocation(Builder: BuilderRef, Inst: ValueRef);
+
+    /* Terminators */
+    pub fn LLVMBuildRetVoid(B: BuilderRef) -> ValueRef;
+    pub fn LLVMBuildRet(B: BuilderRef, V: ValueRef) -> ValueRef;
+    pub fn LLVMBuildAggregateRet(B: BuilderRef,
+                                 RetVals: *const ValueRef,
+                                 N: c_uint)
+                                 -> ValueRef;
+    pub fn LLVMBuildBr(B: BuilderRef, Dest: BasicBlockRef) -> ValueRef;
+    pub fn LLVMBuildCondBr(B: BuilderRef,
+                           If: ValueRef,
+                           Then: BasicBlockRef,
+                           Else: BasicBlockRef)
+                           -> ValueRef;
+    pub fn LLVMBuildSwitch(B: BuilderRef,
+                           V: ValueRef,
+                           Else: BasicBlockRef,
+                           NumCases: c_uint)
+                           -> ValueRef;
+    pub fn LLVMBuildIndirectBr(B: BuilderRef,
+                               Addr: ValueRef,
+                               NumDests: c_uint)
+                               -> ValueRef;
+    pub fn LLVMRustBuildInvoke(B: BuilderRef,
+                               Fn: ValueRef,
+                               Args: *const ValueRef,
+                               NumArgs: c_uint,
+                               Then: BasicBlockRef,
+                               Catch: BasicBlockRef,
+                               Bundle: OperandBundleDefRef,
+                               Name: *const c_char)
+                               -> ValueRef;
+    pub fn LLVMRustBuildLandingPad(B: BuilderRef,
+                                   Ty: TypeRef,
+                                   PersFn: ValueRef,
+                                   NumClauses: c_uint,
+                                   Name: *const c_char,
+                                   F: ValueRef)
+                                   -> ValueRef;
+    pub fn LLVMBuildResume(B: BuilderRef, Exn: ValueRef) -> ValueRef;
+    pub fn LLVMBuildUnreachable(B: BuilderRef) -> ValueRef;
+
+    pub fn LLVMRustBuildCleanupPad(B: BuilderRef,
+                                   ParentPad: ValueRef,
+                                   ArgCnt: c_uint,
+                                   Args: *const ValueRef,
+                                   Name: *const c_char) -> ValueRef;
+    pub fn LLVMRustBuildCleanupRet(B: BuilderRef,
+                                   CleanupPad: ValueRef,
+                                   UnwindBB: BasicBlockRef) -> ValueRef;
+    pub fn LLVMRustBuildCatchPad(B: BuilderRef,
+                                 ParentPad: ValueRef,
+                                 ArgCnt: c_uint,
+                                 Args: *const ValueRef,
+                                 Name: *const c_char) -> ValueRef;
+    pub fn LLVMRustBuildCatchRet(B: BuilderRef,
+                                 Pad: ValueRef,
+                                 BB: BasicBlockRef) -> ValueRef;
+    pub fn LLVMRustBuildCatchSwitch(Builder: BuilderRef,
+                                    ParentPad: ValueRef,
+                                    BB: BasicBlockRef,
+                                    NumHandlers: c_uint,
+                                    Name: *const c_char) -> ValueRef;
+    pub fn LLVMRustAddHandler(CatchSwitch: ValueRef,
+                              Handler: BasicBlockRef);
+    pub fn LLVMRustSetPersonalityFn(B: BuilderRef, Pers: ValueRef);
+
+    /* Add a case to the switch instruction */
+    pub fn LLVMAddCase(Switch: ValueRef,
+                       OnVal: ValueRef,
+                       Dest: BasicBlockRef);
+
+    /* Add a destination to the indirectbr instruction */
+    pub fn LLVMAddDestination(IndirectBr: ValueRef, Dest: BasicBlockRef);
+
+    /* Add a clause to the landing pad instruction */
+    pub fn LLVMAddClause(LandingPad: ValueRef, ClauseVal: ValueRef);
+
+    /* Set the cleanup on a landing pad instruction */
+    pub fn LLVMSetCleanup(LandingPad: ValueRef, Val: Bool);
+
+    /* Arithmetic */
+    pub fn LLVMBuildAdd(B: BuilderRef,
+                        LHS: ValueRef,
+                        RHS: ValueRef,
+                        Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMBuildNSWAdd(B: BuilderRef,
+                           LHS: ValueRef,
+                           RHS: ValueRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildNUWAdd(B: BuilderRef,
+                           LHS: ValueRef,
+                           RHS: ValueRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildFAdd(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildSub(B: BuilderRef,
+                        LHS: ValueRef,
+                        RHS: ValueRef,
+                        Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMBuildNSWSub(B: BuilderRef,
+                           LHS: ValueRef,
+                           RHS: ValueRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildNUWSub(B: BuilderRef,
+                           LHS: ValueRef,
+                           RHS: ValueRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildFSub(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildMul(B: BuilderRef,
+                        LHS: ValueRef,
+                        RHS: ValueRef,
+                        Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMBuildNSWMul(B: BuilderRef,
+                           LHS: ValueRef,
+                           RHS: ValueRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildNUWMul(B: BuilderRef,
+                           LHS: ValueRef,
+                           RHS: ValueRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildFMul(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildUDiv(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildSDiv(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildExactSDiv(B: BuilderRef,
+                              LHS: ValueRef,
+                              RHS: ValueRef,
+                              Name: *const c_char)
+                              -> ValueRef;
+    pub fn LLVMBuildFDiv(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildURem(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildSRem(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildFRem(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildShl(B: BuilderRef,
+                        LHS: ValueRef,
+                        RHS: ValueRef,
+                        Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMBuildLShr(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildAShr(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildAnd(B: BuilderRef,
+                        LHS: ValueRef,
+                        RHS: ValueRef,
+                        Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMBuildOr(B: BuilderRef,
+                       LHS: ValueRef,
+                       RHS: ValueRef,
+                       Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildXor(B: BuilderRef,
+                        LHS: ValueRef,
+                        RHS: ValueRef,
+                        Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMBuildBinOp(B: BuilderRef,
+                          Op: Opcode,
+                          LHS: ValueRef,
+                          RHS: ValueRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+    pub fn LLVMBuildNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMBuildNSWNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildNUWNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildFNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildNot(B: BuilderRef, V: ValueRef, Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMRustSetHasUnsafeAlgebra(Instr: ValueRef);
+
+    /* Memory */
+    pub fn LLVMBuildAlloca(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildFree(B: BuilderRef, PointerVal: ValueRef) -> ValueRef;
+    pub fn LLVMBuildLoad(B: BuilderRef,
+                         PointerVal: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+
+    pub fn LLVMBuildStore(B: BuilderRef, Val: ValueRef, Ptr: ValueRef)
+                          -> ValueRef;
+
+    pub fn LLVMBuildGEP(B: BuilderRef,
+                        Pointer: ValueRef,
+                        Indices: *const ValueRef,
+                        NumIndices: c_uint,
+                        Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMBuildInBoundsGEP(B: BuilderRef,
+                                Pointer: ValueRef,
+                                Indices: *const ValueRef,
+                                NumIndices: c_uint,
+                                Name: *const c_char)
+                                -> ValueRef;
+    pub fn LLVMBuildStructGEP(B: BuilderRef,
+                              Pointer: ValueRef,
+                              Idx: c_uint,
+                              Name: *const c_char)
+                              -> ValueRef;
+    pub fn LLVMBuildGlobalString(B: BuilderRef,
+                                 Str: *const c_char,
+                                 Name: *const c_char)
+                                 -> ValueRef;
+    pub fn LLVMBuildGlobalStringPtr(B: BuilderRef,
+                                    Str: *const c_char,
+                                    Name: *const c_char)
+                                    -> ValueRef;
+
+    /* Casts */
+    pub fn LLVMBuildTrunc(B: BuilderRef,
+                          Val: ValueRef,
+                          DestTy: TypeRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+    pub fn LLVMBuildZExt(B: BuilderRef,
+                         Val: ValueRef,
+                         DestTy: TypeRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildSExt(B: BuilderRef,
+                         Val: ValueRef,
+                         DestTy: TypeRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildFPToUI(B: BuilderRef,
+                           Val: ValueRef,
+                           DestTy: TypeRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildFPToSI(B: BuilderRef,
+                           Val: ValueRef,
+                           DestTy: TypeRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildUIToFP(B: BuilderRef,
+                           Val: ValueRef,
+                           DestTy: TypeRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildSIToFP(B: BuilderRef,
+                           Val: ValueRef,
+                           DestTy: TypeRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildFPTrunc(B: BuilderRef,
+                            Val: ValueRef,
+                            DestTy: TypeRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+    pub fn LLVMBuildFPExt(B: BuilderRef,
+                          Val: ValueRef,
+                          DestTy: TypeRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+    pub fn LLVMBuildPtrToInt(B: BuilderRef,
+                             Val: ValueRef,
+                             DestTy: TypeRef,
+                             Name: *const c_char)
+                             -> ValueRef;
+    pub fn LLVMBuildIntToPtr(B: BuilderRef,
+                             Val: ValueRef,
+                             DestTy: TypeRef,
+                             Name: *const c_char)
+                             -> ValueRef;
+    pub fn LLVMBuildBitCast(B: BuilderRef,
+                            Val: ValueRef,
+                            DestTy: TypeRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+    pub fn LLVMBuildZExtOrBitCast(B: BuilderRef,
+                                  Val: ValueRef,
+                                  DestTy: TypeRef,
+                                  Name: *const c_char)
+                                  -> ValueRef;
+    pub fn LLVMBuildSExtOrBitCast(B: BuilderRef,
+                                  Val: ValueRef,
+                                  DestTy: TypeRef,
+                                  Name: *const c_char)
+                                  -> ValueRef;
+    pub fn LLVMBuildTruncOrBitCast(B: BuilderRef,
+                                   Val: ValueRef,
+                                   DestTy: TypeRef,
+                                   Name: *const c_char)
+                                   -> ValueRef;
+    pub fn LLVMBuildCast(B: BuilderRef,
+                         Op: Opcode,
+                         Val: ValueRef,
+                         DestTy: TypeRef,
+                         Name: *const c_char) -> ValueRef;
+    pub fn LLVMBuildPointerCast(B: BuilderRef,
+                                Val: ValueRef,
+                                DestTy: TypeRef,
+                                Name: *const c_char)
+                                -> ValueRef;
+    pub fn LLVMBuildIntCast(B: BuilderRef,
+                            Val: ValueRef,
+                            DestTy: TypeRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+    pub fn LLVMBuildFPCast(B: BuilderRef,
+                           Val: ValueRef,
+                           DestTy: TypeRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+
+    /* Comparisons */
+    pub fn LLVMBuildICmp(B: BuilderRef,
+                         Op: c_uint,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildFCmp(B: BuilderRef,
+                         Op: c_uint,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+
+    /* Miscellaneous instructions */
+    pub fn LLVMBuildPhi(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMRustBuildCall(B: BuilderRef,
+                             Fn: ValueRef,
+                             Args: *const ValueRef,
+                             NumArgs: c_uint,
+                             Bundle: OperandBundleDefRef,
+                             Name: *const c_char)
+                             -> ValueRef;
+    pub fn LLVMBuildSelect(B: BuilderRef,
+                           If: ValueRef,
+                           Then: ValueRef,
+                           Else: ValueRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildVAArg(B: BuilderRef,
+                          list: ValueRef,
+                          Ty: TypeRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+    pub fn LLVMBuildExtractElement(B: BuilderRef,
+                                   VecVal: ValueRef,
+                                   Index: ValueRef,
+                                   Name: *const c_char)
+                                   -> ValueRef;
+    pub fn LLVMBuildInsertElement(B: BuilderRef,
+                                  VecVal: ValueRef,
+                                  EltVal: ValueRef,
+                                  Index: ValueRef,
+                                  Name: *const c_char)
+                                  -> ValueRef;
+    pub fn LLVMBuildShuffleVector(B: BuilderRef,
+                                  V1: ValueRef,
+                                  V2: ValueRef,
+                                  Mask: ValueRef,
+                                  Name: *const c_char)
+                                  -> ValueRef;
+    pub fn LLVMBuildExtractValue(B: BuilderRef,
+                                 AggVal: ValueRef,
+                                 Index: c_uint,
+                                 Name: *const c_char)
+                                 -> ValueRef;
+    pub fn LLVMBuildInsertValue(B: BuilderRef,
+                                AggVal: ValueRef,
+                                EltVal: ValueRef,
+                                Index: c_uint,
+                                Name: *const c_char)
+                                -> ValueRef;
+
+    pub fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef, Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *const c_char)
+                              -> ValueRef;
+    pub fn LLVMBuildPtrDiff(B: BuilderRef,
+                            LHS: ValueRef,
+                            RHS: ValueRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+
+    /* Atomic Operations */
+    pub fn LLVMRustBuildAtomicLoad(B: BuilderRef,
+                                   PointerVal: ValueRef,
+                                   Name: *const c_char,
+                                   Order: AtomicOrdering,
+                                   Alignment: c_uint)
+                                   -> ValueRef;
+
+    pub fn LLVMRustBuildAtomicStore(B: BuilderRef,
+                                    Val: ValueRef,
+                                    Ptr: ValueRef,
+                                    Order: AtomicOrdering,
+                                    Alignment: c_uint)
+                                    -> ValueRef;
+
+    pub fn LLVMRustBuildAtomicCmpXchg(B: BuilderRef,
+                                      LHS: ValueRef,
+                                      CMP: ValueRef,
+                                      RHS: ValueRef,
+                                      Order: AtomicOrdering,
+                                      FailureOrder: AtomicOrdering,
+                                      Weak: Bool)
+                                      -> ValueRef;
+
+    pub fn LLVMBuildAtomicRMW(B: BuilderRef,
+                              Op: AtomicRmwBinOp,
+                              LHS: ValueRef,
+                              RHS: ValueRef,
+                              Order: AtomicOrdering,
+                              SingleThreaded: Bool)
+                              -> ValueRef;
+
+    pub fn LLVMRustBuildAtomicFence(B: BuilderRef,
+                                    Order: AtomicOrdering,
+                                    Scope: SynchronizationScope);
+
+
+    /* Selected entries from the downcasts. */
+    pub fn LLVMIsATerminatorInst(Inst: ValueRef) -> ValueRef;
+    pub fn LLVMIsAStoreInst(Inst: ValueRef) -> ValueRef;
+
+    /// Writes a module to the specified path. Returns 0 on success.
+    pub fn LLVMWriteBitcodeToFile(M: ModuleRef, Path: *const c_char) -> c_int;
+
+    /// Creates target data from a target layout string.
+    pub fn LLVMCreateTargetData(StringRep: *const c_char) -> TargetDataRef;
+    /// Number of bytes clobbered when doing a Store to *T.
+    pub fn LLVMStoreSizeOfType(TD: TargetDataRef, Ty: TypeRef)
+                               -> c_ulonglong;
+
+    /// Number of bytes clobbered when doing a Store to *T.
+    pub fn LLVMSizeOfTypeInBits(TD: TargetDataRef, Ty: TypeRef)
+                                -> c_ulonglong;
+
+    /// Distance between successive elements in an array of T. Includes ABI padding.
+    pub fn LLVMABISizeOfType(TD: TargetDataRef, Ty: TypeRef) -> c_ulonglong;
+
+    /// Returns the preferred alignment of a type.
+    pub fn LLVMPreferredAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
+                                        -> c_uint;
+    /// Returns the minimum alignment of a type.
+    pub fn LLVMABIAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
+                                  -> c_uint;
+
+    /// Computes the byte offset of the indexed struct element for a
+    /// target.
+    pub fn LLVMOffsetOfElement(TD: TargetDataRef,
+                               StructTy: TypeRef,
+                               Element: c_uint)
+                               -> c_ulonglong;
+
+    /// Returns the minimum alignment of a type when part of a call frame.
+    pub fn LLVMCallFrameAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
+                                        -> c_uint;
+
+    /// Disposes target data.
+    pub fn LLVMDisposeTargetData(TD: TargetDataRef);
+
+    /// Creates a pass manager.
+    pub fn LLVMCreatePassManager() -> PassManagerRef;
+
+    /// Creates a function-by-function pass manager
+    pub fn LLVMCreateFunctionPassManagerForModule(M: ModuleRef)
+                                                  -> PassManagerRef;
+
+    /// Disposes a pass manager.
+    pub fn LLVMDisposePassManager(PM: PassManagerRef);
+
+    /// Runs a pass manager on a module.
+    pub fn LLVMRunPassManager(PM: PassManagerRef, M: ModuleRef) -> Bool;
+
+    /// Runs the function passes on the provided function.
+    pub fn LLVMRunFunctionPassManager(FPM: PassManagerRef, F: ValueRef)
+                                      -> Bool;
+
+    /// Initializes all the function passes scheduled in the manager
+    pub fn LLVMInitializeFunctionPassManager(FPM: PassManagerRef) -> Bool;
+
+    /// Finalizes all the function passes scheduled in the manager
+    pub fn LLVMFinalizeFunctionPassManager(FPM: PassManagerRef) -> Bool;
+
+    pub fn LLVMInitializePasses();
+
+    /// Adds a verification pass.
+    pub fn LLVMAddVerifierPass(PM: PassManagerRef);
+
+    pub fn LLVMAddGlobalOptimizerPass(PM: PassManagerRef);
+    pub fn LLVMAddIPSCCPPass(PM: PassManagerRef);
+    pub fn LLVMAddDeadArgEliminationPass(PM: PassManagerRef);
+    pub fn LLVMAddInstructionCombiningPass(PM: PassManagerRef);
+    pub fn LLVMAddCFGSimplificationPass(PM: PassManagerRef);
+    pub fn LLVMAddFunctionInliningPass(PM: PassManagerRef);
+    pub fn LLVMAddFunctionAttrsPass(PM: PassManagerRef);
+    pub fn LLVMAddScalarReplAggregatesPass(PM: PassManagerRef);
+    pub fn LLVMAddScalarReplAggregatesPassSSA(PM: PassManagerRef);
+    pub fn LLVMAddJumpThreadingPass(PM: PassManagerRef);
+    pub fn LLVMAddConstantPropagationPass(PM: PassManagerRef);
+    pub fn LLVMAddReassociatePass(PM: PassManagerRef);
+    pub fn LLVMAddLoopRotatePass(PM: PassManagerRef);
+    pub fn LLVMAddLICMPass(PM: PassManagerRef);
+    pub fn LLVMAddLoopUnswitchPass(PM: PassManagerRef);
+    pub fn LLVMAddLoopDeletionPass(PM: PassManagerRef);
+    pub fn LLVMAddLoopUnrollPass(PM: PassManagerRef);
+    pub fn LLVMAddGVNPass(PM: PassManagerRef);
+    pub fn LLVMAddMemCpyOptPass(PM: PassManagerRef);
+    pub fn LLVMAddSCCPPass(PM: PassManagerRef);
+    pub fn LLVMAddDeadStoreEliminationPass(PM: PassManagerRef);
+    pub fn LLVMAddStripDeadPrototypesPass(PM: PassManagerRef);
+    pub fn LLVMAddConstantMergePass(PM: PassManagerRef);
+    pub fn LLVMAddArgumentPromotionPass(PM: PassManagerRef);
+    pub fn LLVMAddTailCallEliminationPass(PM: PassManagerRef);
+    pub fn LLVMAddIndVarSimplifyPass(PM: PassManagerRef);
+    pub fn LLVMAddAggressiveDCEPass(PM: PassManagerRef);
+    pub fn LLVMAddGlobalDCEPass(PM: PassManagerRef);
+    pub fn LLVMAddCorrelatedValuePropagationPass(PM: PassManagerRef);
+    pub fn LLVMAddPruneEHPass(PM: PassManagerRef);
+    pub fn LLVMAddSimplifyLibCallsPass(PM: PassManagerRef);
+    pub fn LLVMAddLoopIdiomPass(PM: PassManagerRef);
+    pub fn LLVMAddEarlyCSEPass(PM: PassManagerRef);
+    pub fn LLVMAddTypeBasedAliasAnalysisPass(PM: PassManagerRef);
+    pub fn LLVMAddBasicAliasAnalysisPass(PM: PassManagerRef);
+
+    pub fn LLVMPassManagerBuilderCreate() -> PassManagerBuilderRef;
+    pub fn LLVMPassManagerBuilderDispose(PMB: PassManagerBuilderRef);
+    pub fn LLVMPassManagerBuilderSetOptLevel(PMB: PassManagerBuilderRef,
+                                             OptimizationLevel: c_uint);
+    pub fn LLVMPassManagerBuilderSetSizeLevel(PMB: PassManagerBuilderRef,
+                                              Value: Bool);
+    pub fn LLVMPassManagerBuilderSetDisableUnitAtATime(
+        PMB: PassManagerBuilderRef,
+        Value: Bool);
+    pub fn LLVMPassManagerBuilderSetDisableUnrollLoops(
+        PMB: PassManagerBuilderRef,
+        Value: Bool);
+    pub fn LLVMPassManagerBuilderSetDisableSimplifyLibCalls(
+        PMB: PassManagerBuilderRef,
+        Value: Bool);
+    pub fn LLVMPassManagerBuilderUseInlinerWithThreshold(
+        PMB: PassManagerBuilderRef,
+        threshold: c_uint);
+    pub fn LLVMPassManagerBuilderPopulateModulePassManager(
+        PMB: PassManagerBuilderRef,
+        PM: PassManagerRef);
+
+    pub fn LLVMPassManagerBuilderPopulateFunctionPassManager(
+        PMB: PassManagerBuilderRef,
+        PM: PassManagerRef);
+    pub fn LLVMPassManagerBuilderPopulateLTOPassManager(
+        PMB: PassManagerBuilderRef,
+        PM: PassManagerRef,
+        Internalize: Bool,
+        RunInliner: Bool);
+
+    /// Destroys a memory buffer.
+    pub fn LLVMDisposeMemoryBuffer(MemBuf: MemoryBufferRef);
+
+
+    /* Stuff that's in rustllvm/ because it's not upstream yet. */
+
+    /// Opens an object file.
+    pub fn LLVMCreateObjectFile(MemBuf: MemoryBufferRef) -> ObjectFileRef;
+    /// Closes an object file.
+    pub fn LLVMDisposeObjectFile(ObjFile: ObjectFileRef);
+
+    /// Enumerates the sections in an object file.
+    pub fn LLVMGetSections(ObjFile: ObjectFileRef) -> SectionIteratorRef;
+    /// Destroys a section iterator.
+    pub fn LLVMDisposeSectionIterator(SI: SectionIteratorRef);
+    /// Returns true if the section iterator is at the end of the section
+    /// list:
+    pub fn LLVMIsSectionIteratorAtEnd(ObjFile: ObjectFileRef,
+                                      SI: SectionIteratorRef)
+                                      -> Bool;
+    /// Moves the section iterator to point to the next section.
+    pub fn LLVMMoveToNextSection(SI: SectionIteratorRef);
+    /// Returns the current section size.
+    pub fn LLVMGetSectionSize(SI: SectionIteratorRef) -> c_ulonglong;
+    /// Returns the current section contents as a string buffer.
+    pub fn LLVMGetSectionContents(SI: SectionIteratorRef) -> *const c_char;
+
+    /// Reads the given file and returns it as a memory buffer. Use
+    /// LLVMDisposeMemoryBuffer() to get rid of it.
+    pub fn LLVMRustCreateMemoryBufferWithContentsOfFile(Path: *const c_char)
+                                                        -> MemoryBufferRef;
+    /// Borrows the contents of the memory buffer (doesn't copy it)
+    pub fn LLVMCreateMemoryBufferWithMemoryRange(InputData: *const c_char,
+                                                 InputDataLength: size_t,
+                                                 BufferName: *const c_char,
+                                                 RequiresNull: Bool)
+                                                 -> MemoryBufferRef;
+    pub fn LLVMCreateMemoryBufferWithMemoryRangeCopy(InputData: *const c_char,
+                                                     InputDataLength: size_t,
+                                                     BufferName: *const c_char)
+                                                     -> MemoryBufferRef;
+
+    pub fn LLVMIsMultithreaded() -> Bool;
+    pub fn LLVMStartMultithreaded() -> Bool;
+
+    /// Returns a string describing the last error caused by an LLVMRust* call.
+    pub fn LLVMRustGetLastError() -> *const c_char;
+
+    /// Print the pass timings since static dtors aren't picking them up.
+    pub fn LLVMRustPrintPassTimings();
+
+    pub fn LLVMStructCreateNamed(C: ContextRef, Name: *const c_char) -> TypeRef;
+
+    pub fn LLVMStructSetBody(StructTy: TypeRef,
+                             ElementTypes: *const TypeRef,
+                             ElementCount: c_uint,
+                             Packed: Bool);
+
+    pub fn LLVMConstNamedStruct(S: TypeRef,
+                                ConstantVals: *const ValueRef,
+                                Count: c_uint)
+                                -> ValueRef;
+
+    /// Enables LLVM debug output.
+    pub fn LLVMRustSetDebug(Enabled: c_int);
+
+    /// Prepares inline assembly.
+    pub fn LLVMRustInlineAsm(Ty: TypeRef,
+                             AsmString: *const c_char,
+                             Constraints: *const c_char,
+                             SideEffects: Bool,
+                             AlignStack: Bool,
+                             Dialect: AsmDialect)
+                             -> ValueRef;
+
+    pub fn LLVMRustDebugMetadataVersion() -> u32;
+    pub fn LLVMRustVersionMajor() -> u32;
+    pub fn LLVMRustVersionMinor() -> u32;
+
+    pub fn LLVMRustAddModuleFlag(M: ModuleRef,
+                                 name: *const c_char,
+                                 value: u32);
+
+    pub fn LLVMRustDIBuilderCreate(M: ModuleRef) -> DIBuilderRef;
+
+    pub fn LLVMRustDIBuilderDispose(Builder: DIBuilderRef);
+
+    pub fn LLVMRustDIBuilderFinalize(Builder: DIBuilderRef);
+
+    pub fn LLVMRustDIBuilderCreateCompileUnit(Builder: DIBuilderRef,
+                                              Lang: c_uint,
+                                              File: *const c_char,
+                                              Dir: *const c_char,
+                                              Producer: *const c_char,
+                                              isOptimized: bool,
+                                              Flags: *const c_char,
+                                              RuntimeVer: c_uint,
+                                              SplitName: *const c_char)
+                                              -> DIDescriptor;
+
+    pub fn LLVMRustDIBuilderCreateFile(Builder: DIBuilderRef,
+                                       Filename: *const c_char,
+                                       Directory: *const c_char)
+                                       -> DIFile;
+
+    pub fn LLVMRustDIBuilderCreateSubroutineType(Builder: DIBuilderRef,
+                                                 File: DIFile,
+                                                 ParameterTypes: DIArray)
+                                                 -> DICompositeType;
+
+    pub fn LLVMRustDIBuilderCreateFunction(Builder: DIBuilderRef,
+                                           Scope: DIDescriptor,
+                                           Name: *const c_char,
+                                           LinkageName: *const c_char,
+                                           File: DIFile,
+                                           LineNo: c_uint,
+                                           Ty: DIType,
+                                           isLocalToUnit: bool,
+                                           isDefinition: bool,
+                                           ScopeLine: c_uint,
+                                           Flags: c_uint,
+                                           isOptimized: bool,
+                                           Fn: ValueRef,
+                                           TParam: DIArray,
+                                           Decl: DIDescriptor)
+                                           -> DISubprogram;
+
+    pub fn LLVMRustDIBuilderCreateBasicType(Builder: DIBuilderRef,
+                                            Name: *const c_char,
+                                            SizeInBits: u64,
+                                            AlignInBits: u64,
+                                            Encoding: c_uint)
+                                            -> DIBasicType;
+
+    pub fn LLVMRustDIBuilderCreatePointerType(Builder: DIBuilderRef,
+                                          PointeeTy: DIType,
+                                          SizeInBits: u64,
+                                          AlignInBits: u64,
+                                          Name: *const c_char)
+                                          -> DIDerivedType;
+
+    pub fn LLVMRustDIBuilderCreateStructType(Builder: DIBuilderRef,
+                                             Scope: DIDescriptor,
+                                             Name: *const c_char,
+                                             File: DIFile,
+                                             LineNumber: c_uint,
+                                             SizeInBits: u64,
+                                             AlignInBits: u64,
+                                             Flags: c_uint,
+                                             DerivedFrom: DIType,
+                                             Elements: DIArray,
+                                             RunTimeLang: c_uint,
+                                             VTableHolder: DIType,
+                                             UniqueId: *const c_char)
+                                             -> DICompositeType;
+
+    pub fn LLVMRustDIBuilderCreateMemberType(Builder: DIBuilderRef,
+                                             Scope: DIDescriptor,
+                                             Name: *const c_char,
+                                             File: DIFile,
+                                             LineNo: c_uint,
+                                             SizeInBits: u64,
+                                             AlignInBits: u64,
+                                             OffsetInBits: u64,
+                                             Flags: c_uint,
+                                             Ty: DIType)
+                                             -> DIDerivedType;
+
+    pub fn LLVMRustDIBuilderCreateLexicalBlock(Builder: DIBuilderRef,
+                                               Scope: DIScope,
+                                               File: DIFile,
+                                               Line: c_uint,
+                                               Col: c_uint)
+                                               -> DILexicalBlock;
+
+    pub fn LLVMRustDIBuilderCreateStaticVariable(Builder: DIBuilderRef,
+                                                 Context: DIScope,
+                                                 Name: *const c_char,
+                                                 LinkageName: *const c_char,
+                                                 File: DIFile,
+                                                 LineNo: c_uint,
+                                                 Ty: DIType,
+                                                 isLocalToUnit: bool,
+                                                 Val: ValueRef,
+                                                 Decl: DIDescriptor)
+                                                 -> DIGlobalVariable;
+
+    pub fn LLVMRustDIBuilderCreateVariable(Builder: DIBuilderRef,
+                                           Tag: c_uint,
+                                           Scope: DIDescriptor,
+                                           Name: *const c_char,
+                                           File: DIFile,
+                                           LineNo: c_uint,
+                                           Ty: DIType,
+                                           AlwaysPreserve: bool,
+                                           Flags: c_uint,
+                                           AddrOps: *const i64,
+                                           AddrOpsCount: c_uint,
+                                           ArgNo: c_uint)
+                                           -> DIVariable;
+
+    pub fn LLVMRustDIBuilderCreateArrayType(Builder: DIBuilderRef,
+                                            Size: u64,
+                                            AlignInBits: u64,
+                                            Ty: DIType,
+                                            Subscripts: DIArray)
+                                            -> DIType;
+
+    pub fn LLVMRustDIBuilderCreateVectorType(Builder: DIBuilderRef,
+                                             Size: u64,
+                                             AlignInBits: u64,
+                                             Ty: DIType,
+                                             Subscripts: DIArray)
+                                             -> DIType;
+
+    pub fn LLVMRustDIBuilderGetOrCreateSubrange(Builder: DIBuilderRef,
+                                                Lo: i64,
+                                                Count: i64)
+                                                -> DISubrange;
+
+    pub fn LLVMRustDIBuilderGetOrCreateArray(Builder: DIBuilderRef,
+                                             Ptr: *const DIDescriptor,
+                                             Count: c_uint)
+                                             -> DIArray;
+
+    pub fn LLVMRustDIBuilderInsertDeclareAtEnd(Builder: DIBuilderRef,
+                                               Val: ValueRef,
+                                               VarInfo: DIVariable,
+                                               AddrOps: *const i64,
+                                               AddrOpsCount: c_uint,
+                                               DL: ValueRef,
+                                               InsertAtEnd: BasicBlockRef)
+                                               -> ValueRef;
+
+    pub fn LLVMRustDIBuilderInsertDeclareBefore(Builder: DIBuilderRef,
+                                                Val: ValueRef,
+                                                VarInfo: DIVariable,
+                                                AddrOps: *const i64,
+                                                AddrOpsCount: c_uint,
+                                                DL: ValueRef,
+                                                InsertBefore: ValueRef)
+                                                -> ValueRef;
+
+    pub fn LLVMRustDIBuilderCreateEnumerator(Builder: DIBuilderRef,
+                                             Name: *const c_char,
+                                             Val: u64)
+                                             -> DIEnumerator;
+
+    pub fn LLVMRustDIBuilderCreateEnumerationType(Builder: DIBuilderRef,
+                                                  Scope: DIScope,
+                                                  Name: *const c_char,
+                                                  File: DIFile,
+                                                  LineNumber: c_uint,
+                                                  SizeInBits: u64,
+                                                  AlignInBits: u64,
+                                                  Elements: DIArray,
+                                                  ClassType: DIType)
+                                                  -> DIType;
+
+    pub fn LLVMRustDIBuilderCreateUnionType(Builder: DIBuilderRef,
+                                            Scope: DIScope,
+                                            Name: *const c_char,
+                                            File: DIFile,
+                                            LineNumber: c_uint,
+                                            SizeInBits: u64,
+                                            AlignInBits: u64,
+                                            Flags: c_uint,
+                                            Elements: DIArray,
+                                            RunTimeLang: c_uint,
+                                            UniqueId: *const c_char)
+                                            -> DIType;
+
+    pub fn LLVMSetUnnamedAddr(GlobalVar: ValueRef, UnnamedAddr: Bool);
+
+    pub fn LLVMRustDIBuilderCreateTemplateTypeParameter(Builder: DIBuilderRef,
+                                                        Scope: DIScope,
+                                                        Name: *const c_char,
+                                                        Ty: DIType,
+                                                        File: DIFile,
+                                                        LineNo: c_uint,
+                                                        ColumnNo: c_uint)
+                                                        -> DITemplateTypeParameter;
+
+
+    pub fn LLVMRustDIBuilderCreateNameSpace(Builder: DIBuilderRef,
+                                            Scope: DIScope,
+                                            Name: *const c_char,
+                                            File: DIFile,
+                                            LineNo: c_uint)
+                                            -> DINameSpace;
+    pub fn LLVMRustDICompositeTypeSetTypeArray(Builder: DIBuilderRef,
+                                               CompositeType: DIType,
+                                               TypeArray: DIArray);
+
+
+    pub fn LLVMRustDIBuilderCreateDebugLocation(Context: ContextRef,
+                                                Line: c_uint,
+                                                Column: c_uint,
+                                                Scope: DIScope,
+                                                InlinedAt: MetadataRef)
+                                                -> ValueRef;
+    pub fn LLVMRustDIBuilderCreateOpDeref() -> i64;
+    pub fn LLVMRustDIBuilderCreateOpPlus() -> i64;
+
+    pub fn LLVMRustWriteTypeToString(Type: TypeRef, s: RustStringRef);
+    pub fn LLVMRustWriteValueToString(value_ref: ValueRef, s: RustStringRef);
+
+    pub fn LLVMIsAArgument(value_ref: ValueRef) -> ValueRef;
+
+    pub fn LLVMIsAAllocaInst(value_ref: ValueRef) -> ValueRef;
+    pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef;
+
+    pub fn LLVMRustPassKind(Pass: PassRef) -> PassKind;
+    pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> PassRef;
+    pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: PassRef);
+
+    pub fn LLVMRustHasFeature(T: TargetMachineRef,
+                              s: *const c_char) -> bool;
+
+    pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
+                                       CPU: *const c_char,
+                                       Features: *const c_char,
+                                       Model: CodeModel,
+                                       Reloc: RelocMode,
+                                       Level: CodeGenOptLevel,
+                                       UseSoftFP: bool,
+                                       PositionIndependentExecutable: bool,
+                                       FunctionSections: bool,
+                                       DataSections: bool) -> TargetMachineRef;
+    pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef);
+    pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef,
+                                     PM: PassManagerRef,
+                                     M: ModuleRef);
+    pub fn LLVMRustAddBuilderLibraryInfo(PMB: PassManagerBuilderRef,
+                                         M: ModuleRef,
+                                         DisableSimplifyLibCalls: bool);
+    pub fn LLVMRustConfigurePassManagerBuilder(PMB: PassManagerBuilderRef,
+                                               OptLevel: CodeGenOptLevel,
+                                               MergeFunctions: bool,
+                                               SLPVectorize: bool,
+                                               LoopVectorize: bool);
+    pub fn LLVMRustAddLibraryInfo(PM: PassManagerRef, M: ModuleRef,
+                                  DisableSimplifyLibCalls: bool);
+    pub fn LLVMRustRunFunctionPassManager(PM: PassManagerRef, M: ModuleRef);
+    pub fn LLVMRustWriteOutputFile(T: TargetMachineRef,
+                                   PM: PassManagerRef,
+                                   M: ModuleRef,
+                                   Output: *const c_char,
+                                   FileType: FileType)
+                                   -> LLVMRustResult;
+    pub fn LLVMRustPrintModule(PM: PassManagerRef,
+                               M: ModuleRef,
+                               Output: *const c_char);
+    pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char);
+    pub fn LLVMRustPrintPasses();
+    pub fn LLVMRustSetNormalizedTarget(M: ModuleRef, triple: *const c_char);
+    pub fn LLVMRustAddAlwaysInlinePass(P: PassManagerBuilderRef,
+                                       AddLifetimes: bool);
+    pub fn LLVMRustLinkInExternalBitcode(M: ModuleRef,
+                                         bc: *const c_char,
+                                         len: size_t) -> bool;
+    pub fn LLVMRustRunRestrictionPass(M: ModuleRef,
+                                      syms: *const *const c_char,
+                                      len: size_t);
+    pub fn LLVMRustMarkAllFunctionsNounwind(M: ModuleRef);
+
+    pub fn LLVMRustOpenArchive(path: *const c_char) -> ArchiveRef;
+    pub fn LLVMRustArchiveIteratorNew(AR: ArchiveRef) -> ArchiveIteratorRef;
+    pub fn LLVMRustArchiveIteratorNext(AIR: ArchiveIteratorRef) -> ArchiveChildRef;
+    pub fn LLVMRustArchiveChildName(ACR: ArchiveChildRef,
+                                    size: *mut size_t) -> *const c_char;
+    pub fn LLVMRustArchiveChildData(ACR: ArchiveChildRef,
+                                    size: *mut size_t) -> *const c_char;
+    pub fn LLVMRustArchiveChildFree(ACR: ArchiveChildRef);
+    pub fn LLVMRustArchiveIteratorFree(AIR: ArchiveIteratorRef);
+    pub fn LLVMRustDestroyArchive(AR: ArchiveRef);
+
+    pub fn LLVMRustGetSectionName(SI: SectionIteratorRef,
+                                  data: *mut *const c_char) -> size_t;
+
+    pub fn LLVMRustWriteTwineToString(T: TwineRef, s: RustStringRef);
+
+    pub fn LLVMContextSetDiagnosticHandler(C: ContextRef,
+                                           Handler: DiagnosticHandler,
+                                           DiagnosticContext: *mut c_void);
+
+    pub fn LLVMRustUnpackOptimizationDiagnostic(DI: DiagnosticInfoRef,
+                                                pass_name_out: *mut *const c_char,
+                                                function_out: *mut ValueRef,
+                                                debugloc_out: *mut DebugLocRef,
+                                                message_out: *mut TwineRef);
+    pub fn LLVMRustUnpackInlineAsmDiagnostic(DI: DiagnosticInfoRef,
+                                             cookie_out: *mut c_uint,
+                                             message_out: *mut TwineRef,
+                                             instruction_out: *mut ValueRef);
+
+    pub fn LLVMRustWriteDiagnosticInfoToString(DI: DiagnosticInfoRef,
+                                               s: RustStringRef);
+    pub fn LLVMGetDiagInfoSeverity(DI: DiagnosticInfoRef) -> DiagnosticSeverity;
+    pub fn LLVMRustGetDiagInfoKind(DI: DiagnosticInfoRef) -> DiagnosticKind;
+
+    pub fn LLVMRustWriteDebugLocToString(C: ContextRef,
+                                         DL: DebugLocRef,
+                                         s: RustStringRef);
+
+    pub fn LLVMRustSetInlineAsmDiagnosticHandler(C: ContextRef,
+                                                 H: InlineAsmDiagHandler,
+                                                 CX: *mut c_void);
+
+    pub fn LLVMRustWriteSMDiagnosticToString(d: SMDiagnosticRef, s: RustStringRef);
+
+    pub fn LLVMRustWriteArchive(Dst: *const c_char,
+                                NumMembers: size_t,
+                                Members: *const RustArchiveMemberRef,
+                                WriteSymbtab: bool,
+                                Kind: ArchiveKind) ->
+                                LLVMRustResult;
+    pub fn LLVMRustArchiveMemberNew(Filename: *const c_char,
+                                    Name: *const c_char,
+                                    Child: ArchiveChildRef) -> RustArchiveMemberRef;
+    pub fn LLVMRustArchiveMemberFree(Member: RustArchiveMemberRef);
+
+    pub fn LLVMRustSetDataLayoutFromTargetMachine(M: ModuleRef,
+                                                  TM: TargetMachineRef);
+    pub fn LLVMRustGetModuleDataLayout(M: ModuleRef) -> TargetDataRef;
+
+    pub fn LLVMRustBuildOperandBundleDef(Name: *const c_char,
+                                         Inputs: *const ValueRef,
+                                         NumInputs: c_uint)
+                                         -> OperandBundleDefRef;
+    pub fn LLVMRustFreeOperandBundleDef(Bundle: OperandBundleDefRef);
+
+    pub fn LLVMRustPositionBuilderAtStart(B: BuilderRef, BB: BasicBlockRef);
+
+    pub fn LLVMRustSetComdat(M: ModuleRef, V: ValueRef, Name: *const c_char);
+    pub fn LLVMRustUnsetComdat(V: ValueRef);
+    pub fn LLVMRustSetModulePIELevel(M: ModuleRef);
+}
+
+
+// LLVM requires symbols from this library, but apparently they're not printed
+// during llvm-config?
+#[cfg(windows)]
+#[link(name = "ole32")]
+extern {}
index 6905abc2902400451a6e896700cdea4f1556de3e..6c4e1a54ea7281b4ff3d0ae55f9c3ac7c9337e76 100644 (file)
 extern crate libc;
 #[macro_use] #[no_link] extern crate rustc_bitflags;
 
-pub use self::AttributeSet::*;
 pub use self::IntPredicate::*;
 pub use self::RealPredicate::*;
 pub use self::TypeKind::*;
-pub use self::AtomicBinOp::*;
-pub use self::AtomicOrdering::*;
-pub use self::SynchronizationScope::*;
-pub use self::FileType::*;
+pub use self::AtomicRmwBinOp::*;
 pub use self::MetadataType::*;
-pub use self::AsmDialect::*;
-pub use self::CodeGenOptLevel::*;
 pub use self::CodeGenOptSize::*;
-pub use self::RelocMode::*;
-pub use self::CodeGenModel::*;
 pub use self::DiagnosticKind::*;
 pub use self::CallConv::*;
-pub use self::Visibility::*;
 pub use self::DiagnosticSeverity::*;
 pub use self::Linkage::*;
-pub use self::DLLStorageClassTypes::*;
 
 use std::str::FromStr;
+use std::slice;
 use std::ffi::{CString, CStr};
 use std::cell::RefCell;
-use std::slice;
-use libc::{c_uint, c_ushort, uint64_t, c_int, size_t, c_char};
-use libc::{c_longlong, c_ulonglong, c_void};
-use debuginfo::{DIBuilderRef, DIDescriptor,
-                DIFile, DILexicalBlock, DISubprogram, DIType,
-                DIBasicType, DIDerivedType, DICompositeType, DIScope,
-                DIVariable, DIGlobalVariable, DIArray, DISubrange,
-                DITemplateTypeParameter, DIEnumerator, DINameSpace};
+use libc::{c_uint, c_char, size_t};
 
 pub mod archive_ro;
 pub mod diagnostic;
+pub mod ffi;
 
-pub type Opcode = u32;
-pub type Bool = c_uint;
-
-pub const True: Bool = 1 as Bool;
-pub const False: Bool = 0 as Bool;
-
-// Consts for the LLVM CallConv type, pre-cast to usize.
-
-#[derive(Copy, Clone, PartialEq)]
-pub enum CallConv {
-    CCallConv = 0,
-    FastCallConv = 8,
-    ColdCallConv = 9,
-    X86StdcallCallConv = 64,
-    X86FastcallCallConv = 65,
-    X86_64_Win64 = 79,
-    X86_VectorCall = 80
-}
-
-#[derive(Copy, Clone)]
-pub enum Visibility {
-    LLVMDefaultVisibility = 0,
-    HiddenVisibility = 1,
-    ProtectedVisibility = 2,
-}
-
-// This enum omits the obsolete (and no-op) linkage types DLLImportLinkage,
-// DLLExportLinkage, GhostLinkage and LinkOnceODRAutoHideLinkage.
-// LinkerPrivateLinkage and LinkerPrivateWeakLinkage are not included either;
-// they've been removed in upstream LLVM commit r203866.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
-pub enum Linkage {
-    ExternalLinkage = 0,
-    AvailableExternallyLinkage = 1,
-    LinkOnceAnyLinkage = 2,
-    LinkOnceODRLinkage = 3,
-    WeakAnyLinkage = 5,
-    WeakODRLinkage = 6,
-    AppendingLinkage = 7,
-    InternalLinkage = 8,
-    PrivateLinkage = 9,
-    ExternalWeakLinkage = 12,
-    CommonLinkage = 14,
-}
-
-#[repr(C)]
-#[derive(Copy, Clone, Debug)]
-pub enum DiagnosticSeverity {
-    Error,
-    Warning,
-    Remark,
-    Note,
-}
-
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub enum DLLStorageClassTypes {
-    DefaultStorageClass = 0,
-    DLLImportStorageClass = 1,
-    DLLExportStorageClass = 2,
-}
-
-bitflags! {
-    #[derive(Default, Debug)]
-    flags Attribute : u64 {
-        const ZExt            = 1 << 0,
-        const SExt            = 1 << 1,
-        const NoReturn        = 1 << 2,
-        const InReg           = 1 << 3,
-        const StructRet       = 1 << 4,
-        const NoUnwind        = 1 << 5,
-        const NoAlias         = 1 << 6,
-        const ByVal           = 1 << 7,
-        const Nest            = 1 << 8,
-        const ReadNone        = 1 << 9,
-        const ReadOnly        = 1 << 10,
-        const NoInline        = 1 << 11,
-        const AlwaysInline    = 1 << 12,
-        const OptimizeForSize = 1 << 13,
-        const StackProtect    = 1 << 14,
-        const StackProtectReq = 1 << 15,
-        const NoCapture       = 1 << 21,
-        const NoRedZone       = 1 << 22,
-        const NoImplicitFloat = 1 << 23,
-        const Naked           = 1 << 24,
-        const InlineHint      = 1 << 25,
-        const ReturnsTwice    = 1 << 29,
-        const UWTable         = 1 << 30,
-        const NonLazyBind     = 1 << 31,
+pub use ffi::*;
 
-        // Some of these are missing from the LLVM C API, the rest are
-        // present, but commented out, and preceded by the following warning:
-        // FIXME: These attributes are currently not included in the C API as
-        // a temporary measure until the API/ABI impact to the C API is understood
-        // and the path forward agreed upon.
-        const SanitizeAddress = 1 << 32,
-        const MinSize         = 1 << 33,
-        const NoDuplicate     = 1 << 34,
-        const StackProtectStrong = 1 << 35,
-        const SanitizeThread  = 1 << 36,
-        const SanitizeMemory  = 1 << 37,
-        const NoBuiltin       = 1 << 38,
-        const Returned        = 1 << 39,
-        const Cold            = 1 << 40,
-        const Builtin         = 1 << 41,
-        const OptimizeNone    = 1 << 42,
-        const InAlloca        = 1 << 43,
-        const NonNull         = 1 << 44,
-        const JumpTable       = 1 << 45,
-        const Convergent      = 1 << 46,
-        const SafeStack       = 1 << 47,
-        const NoRecurse       = 1 << 48,
-        const InaccessibleMemOnly         = 1 << 49,
-        const InaccessibleMemOrArgMemOnly = 1 << 50,
+impl LLVMRustResult {
+    pub fn into_result(self) -> Result<(), ()> {
+        match self {
+            LLVMRustResult::Success => Ok(()),
+            LLVMRustResult::Failure => Err(()),
+        }
     }
 }
 
@@ -214,167 +92,64 @@ pub fn unset_dereferenceable(&mut self) -> &mut Self {
         self
     }
 
-    pub fn apply_llfn(&self, idx: usize, llfn: ValueRef) {
+    pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
         unsafe {
-            LLVMAddFunctionAttribute(llfn, idx as c_uint, self.regular.bits());
+            self.regular.apply_llfn(idx, llfn);
             if self.dereferenceable_bytes != 0 {
-                LLVMAddDereferenceableAttr(llfn, idx as c_uint,
-                                           self.dereferenceable_bytes);
+                LLVMRustAddDereferenceableAttr(
+                    llfn,
+                    idx.as_uint(),
+                    self.dereferenceable_bytes);
             }
         }
     }
 
-    pub fn apply_callsite(&self, idx: usize, callsite: ValueRef) {
+    pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
         unsafe {
-            LLVMRustAddCallSiteAttribute(callsite, idx as c_uint, self.regular.bits());
+            self.regular.apply_callsite(idx, callsite);
             if self.dereferenceable_bytes != 0 {
-                LLVMAddDereferenceableCallSiteAttr(callsite, idx as c_uint,
-                                                   self.dereferenceable_bytes);
+                LLVMRustAddDereferenceableCallSiteAttr(
+                    callsite,
+                    idx.as_uint(),
+                    self.dereferenceable_bytes);
             }
         }
     }
 }
 
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub enum AttributeSet {
-    ReturnIndex = 0,
-    FunctionIndex = !0
-}
-
-// enum for the LLVM IntPredicate type
-#[derive(Copy, Clone)]
-pub enum IntPredicate {
-    IntEQ = 32,
-    IntNE = 33,
-    IntUGT = 34,
-    IntUGE = 35,
-    IntULT = 36,
-    IntULE = 37,
-    IntSGT = 38,
-    IntSGE = 39,
-    IntSLT = 40,
-    IntSLE = 41,
-}
-
-// enum for the LLVM RealPredicate type
-#[derive(Copy, Clone)]
-pub enum RealPredicate {
-    RealPredicateFalse = 0,
-    RealOEQ = 1,
-    RealOGT = 2,
-    RealOGE = 3,
-    RealOLT = 4,
-    RealOLE = 5,
-    RealONE = 6,
-    RealORD = 7,
-    RealUNO = 8,
-    RealUEQ = 9,
-    RealUGT = 10,
-    RealUGE = 11,
-    RealULT = 12,
-    RealULE = 13,
-    RealUNE = 14,
-    RealPredicateTrue = 15,
-}
-
-// The LLVM TypeKind type - must stay in sync with the def of
-// LLVMTypeKind in llvm/include/llvm-c/Core.h
-#[derive(Copy, Clone, PartialEq, Debug)]
-#[repr(C)]
-pub enum TypeKind {
-    Void      = 0,
-    Half      = 1,
-    Float     = 2,
-    Double    = 3,
-    X86_FP80  = 4,
-    FP128     = 5,
-    PPC_FP128 = 6,
-    Label     = 7,
-    Integer   = 8,
-    Function  = 9,
-    Struct    = 10,
-    Array     = 11,
-    Pointer   = 12,
-    Vector    = 13,
-    Metadata  = 14,
-    X86_MMX   = 15,
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub enum AtomicBinOp {
-    AtomicXchg = 0,
-    AtomicAdd  = 1,
-    AtomicSub  = 2,
-    AtomicAnd  = 3,
-    AtomicNand = 4,
-    AtomicOr   = 5,
-    AtomicXor  = 6,
-    AtomicMax  = 7,
-    AtomicMin  = 8,
-    AtomicUMax = 9,
-    AtomicUMin = 10,
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub enum AtomicOrdering {
-    NotAtomic = 0,
-    Unordered = 1,
-    Monotonic = 2,
-    // Consume = 3,  // Not specified yet.
-    Acquire = 4,
-    Release = 5,
-    AcquireRelease = 6,
-    SequentiallyConsistent = 7
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub enum SynchronizationScope {
-    SingleThread = 0,
-    CrossThread = 1
+pub fn AddFunctionAttrStringValue(
+    llfn: ValueRef,
+    idx: AttributePlace,
+    attr: &'static str,
+    value: &'static str
+) {
+    unsafe {
+        LLVMRustAddFunctionAttrStringValue(
+            llfn,
+            idx.as_uint(),
+            attr.as_ptr() as *const _,
+            value.as_ptr() as *const _)
+    }
 }
 
-// Consts for the LLVMCodeGenFileType type (in include/llvm/c/TargetMachine.h)
 #[repr(C)]
 #[derive(Copy, Clone)]
-pub enum FileType {
-    AssemblyFileType = 0,
-    ObjectFileType = 1
-}
-
-#[derive(Copy, Clone)]
-pub enum MetadataType {
-    MD_dbg = 0,
-    MD_tbaa = 1,
-    MD_prof = 2,
-    MD_fpmath = 3,
-    MD_range = 4,
-    MD_tbaa_struct = 5,
-    MD_invariant_load = 6,
-    MD_alias_scope = 7,
-    MD_noalias = 8,
-    MD_nontemporal = 9,
-    MD_mem_parallel_loop_access = 10,
-    MD_nonnull = 11,
+pub enum AttributePlace {
+    Argument(u32),
+    Function,
 }
 
-// Inline Asm Dialect
-#[derive(Copy, Clone)]
-pub enum AsmDialect {
-    AD_ATT   = 0,
-    AD_Intel = 1
-}
+impl AttributePlace {
+    pub fn ReturnValue() -> Self {
+        AttributePlace::Argument(0)
+    }
 
-#[derive(Copy, Clone, PartialEq)]
-#[repr(C)]
-pub enum CodeGenOptLevel {
-    CodeGenLevelNone = 0,
-    CodeGenLevelLess = 1,
-    CodeGenLevelDefault = 2,
-    CodeGenLevelAggressive = 3,
+    fn as_uint(self) -> c_uint {
+        match self {
+            AttributePlace::Function => !0,
+            AttributePlace::Argument(i) => i,
+        }
+    }
 }
 
 #[derive(Copy, Clone, PartialEq)]
@@ -385,48 +160,6 @@ pub enum CodeGenOptSize {
     CodeGenOptSizeAggressive = 2,
 }
 
-#[derive(Copy, Clone, PartialEq)]
-#[repr(C)]
-pub enum RelocMode {
-    RelocDefault = 0,
-    RelocStatic = 1,
-    RelocPIC = 2,
-    RelocDynamicNoPic = 3,
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub enum CodeGenModel {
-    CodeModelDefault = 0,
-    CodeModelJITDefault = 1,
-    CodeModelSmall = 2,
-    CodeModelKernel = 3,
-    CodeModelMedium = 4,
-    CodeModelLarge = 5,
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub enum DiagnosticKind {
-    DK_InlineAsm = 0,
-    DK_StackSize,
-    DK_DebugMetadataVersion,
-    DK_SampleProfile,
-    DK_OptimizationRemark,
-    DK_OptimizationRemarkMissed,
-    DK_OptimizationRemarkAnalysis,
-    DK_OptimizationFailure,
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub enum ArchiveKind {
-    K_GNU,
-    K_MIPS64,
-    K_BSD,
-    K_COFF,
-}
-
 impl FromStr for ArchiveKind {
     type Err = ();
 
@@ -441,1726 +174,22 @@ fn from_str(s: &str) -> Result<Self, Self::Err> {
     }
 }
 
-/// Represents the different LLVM passes Rust supports
-#[derive(Copy, Clone, PartialEq, Debug)]
-#[repr(C)]
-pub enum SupportedPassKind {
-    Function,
-    Module,
-    Unsupported,
-}
-
-// Opaque pointer types
-#[allow(missing_copy_implementations)]
-pub enum Module_opaque {}
-pub type ModuleRef = *mut Module_opaque;
 #[allow(missing_copy_implementations)]
-pub enum Context_opaque {}
-pub type ContextRef = *mut Context_opaque;
-#[allow(missing_copy_implementations)]
-pub enum Type_opaque {}
-pub type TypeRef = *mut Type_opaque;
-#[allow(missing_copy_implementations)]
-pub enum Value_opaque {}
-pub type ValueRef = *mut Value_opaque;
-#[allow(missing_copy_implementations)]
-pub enum Metadata_opaque {}
-pub type MetadataRef = *mut Metadata_opaque;
-#[allow(missing_copy_implementations)]
-pub enum BasicBlock_opaque {}
-pub type BasicBlockRef = *mut BasicBlock_opaque;
-#[allow(missing_copy_implementations)]
-pub enum Builder_opaque {}
-pub type BuilderRef = *mut Builder_opaque;
-#[allow(missing_copy_implementations)]
-pub enum ExecutionEngine_opaque {}
-pub type ExecutionEngineRef = *mut ExecutionEngine_opaque;
-#[allow(missing_copy_implementations)]
-pub enum MemoryBuffer_opaque {}
-pub type MemoryBufferRef = *mut MemoryBuffer_opaque;
-#[allow(missing_copy_implementations)]
-pub enum PassManager_opaque {}
-pub type PassManagerRef = *mut PassManager_opaque;
-#[allow(missing_copy_implementations)]
-pub enum PassManagerBuilder_opaque {}
-pub type PassManagerBuilderRef = *mut PassManagerBuilder_opaque;
-#[allow(missing_copy_implementations)]
-pub enum Use_opaque {}
-pub type UseRef = *mut Use_opaque;
-#[allow(missing_copy_implementations)]
-pub enum TargetData_opaque {}
-pub type TargetDataRef = *mut TargetData_opaque;
-#[allow(missing_copy_implementations)]
-pub enum ObjectFile_opaque {}
-pub type ObjectFileRef = *mut ObjectFile_opaque;
-#[allow(missing_copy_implementations)]
-pub enum SectionIterator_opaque {}
-pub type SectionIteratorRef = *mut SectionIterator_opaque;
-#[allow(missing_copy_implementations)]
-pub enum Pass_opaque {}
-pub type PassRef = *mut Pass_opaque;
-#[allow(missing_copy_implementations)]
-pub enum TargetMachine_opaque {}
-pub type TargetMachineRef = *mut TargetMachine_opaque;
-pub enum Archive_opaque {}
-pub type ArchiveRef = *mut Archive_opaque;
-pub enum ArchiveIterator_opaque {}
-pub type ArchiveIteratorRef = *mut ArchiveIterator_opaque;
-pub enum ArchiveChild_opaque {}
-pub type ArchiveChildRef = *mut ArchiveChild_opaque;
-#[allow(missing_copy_implementations)]
-pub enum Twine_opaque {}
-pub type TwineRef = *mut Twine_opaque;
-#[allow(missing_copy_implementations)]
-pub enum DiagnosticInfo_opaque {}
-pub type DiagnosticInfoRef = *mut DiagnosticInfo_opaque;
-#[allow(missing_copy_implementations)]
-pub enum DebugLoc_opaque {}
-pub type DebugLocRef = *mut DebugLoc_opaque;
-#[allow(missing_copy_implementations)]
-pub enum SMDiagnostic_opaque {}
-pub type SMDiagnosticRef = *mut SMDiagnostic_opaque;
-#[allow(missing_copy_implementations)]
-pub enum RustArchiveMember_opaque {}
-pub type RustArchiveMemberRef = *mut RustArchiveMember_opaque;
-#[allow(missing_copy_implementations)]
-pub enum OperandBundleDef_opaque {}
-pub type OperandBundleDefRef = *mut OperandBundleDef_opaque;
-
-pub type DiagnosticHandler = unsafe extern "C" fn(DiagnosticInfoRef, *mut c_void);
-pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_void, c_uint);
-
-pub mod debuginfo {
-    pub use self::DIDescriptorFlags::*;
-    use super::{MetadataRef};
-
-    #[allow(missing_copy_implementations)]
-    pub enum DIBuilder_opaque {}
-    pub type DIBuilderRef = *mut DIBuilder_opaque;
-
-    pub type DIDescriptor = MetadataRef;
-    pub type DIScope = DIDescriptor;
-    pub type DILocation = DIDescriptor;
-    pub type DIFile = DIScope;
-    pub type DILexicalBlock = DIScope;
-    pub type DISubprogram = DIScope;
-    pub type DINameSpace = DIScope;
-    pub type DIType = DIDescriptor;
-    pub type DIBasicType = DIType;
-    pub type DIDerivedType = DIType;
-    pub type DICompositeType = DIDerivedType;
-    pub type DIVariable = DIDescriptor;
-    pub type DIGlobalVariable = DIDescriptor;
-    pub type DIArray = DIDescriptor;
-    pub type DISubrange = DIDescriptor;
-    pub type DIEnumerator = DIDescriptor;
-    pub type DITemplateTypeParameter = DIDescriptor;
-
-    #[derive(Copy, Clone)]
-    pub enum DIDescriptorFlags {
-      FlagPrivate            = 1 << 0,
-      FlagProtected          = 1 << 1,
-      FlagFwdDecl            = 1 << 2,
-      FlagAppleBlock         = 1 << 3,
-      FlagBlockByrefStruct   = 1 << 4,
-      FlagVirtual            = 1 << 5,
-      FlagArtificial         = 1 << 6,
-      FlagExplicit           = 1 << 7,
-      FlagPrototyped         = 1 << 8,
-      FlagObjcClassComplete  = 1 << 9,
-      FlagObjectPointer      = 1 << 10,
-      FlagVector             = 1 << 11,
-      FlagStaticMember       = 1 << 12,
-      FlagIndirectVariable   = 1 << 13,
-      FlagLValueReference    = 1 << 14,
-      FlagRValueReference    = 1 << 15
-    }
-}
-
-
-// Link to our native llvm bindings (things that we need to use the C++ api
-// for) and because llvm is written in C++ we need to link against libstdc++
-//
-// You'll probably notice that there is an omission of all LLVM libraries
-// from this location. This is because the set of LLVM libraries that we
-// link to is mostly defined by LLVM, and the `llvm-config` tool is used to
-// figure out the exact set of libraries. To do this, the build system
-// generates an llvmdeps.rs file next to this one which will be
-// automatically updated whenever LLVM is updated to include an up-to-date
-// set of the libraries we need to link to LLVM for.
-#[link(name = "rustllvm", kind = "static")]
-#[cfg(not(cargobuild))]
-extern {}
-
-#[linked_from = "rustllvm"] // not quite true but good enough
-extern {
-    /* Create and destroy contexts. */
-    pub fn LLVMContextCreate() -> ContextRef;
-    pub fn LLVMContextDispose(C: ContextRef);
-    pub fn LLVMGetMDKindIDInContext(C: ContextRef,
-                                    Name: *const c_char,
-                                    SLen: c_uint)
-                                    -> c_uint;
-
-    /* Create and destroy modules. */
-    pub fn LLVMModuleCreateWithNameInContext(ModuleID: *const c_char,
-                                             C: ContextRef)
-                                             -> ModuleRef;
-    pub fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef;
-    pub fn LLVMCloneModule(M: ModuleRef) -> ModuleRef;
-    pub fn LLVMDisposeModule(M: ModuleRef);
-
-    /// Data layout. See Module::getDataLayout.
-    pub fn LLVMGetDataLayout(M: ModuleRef) -> *const c_char;
-    pub fn LLVMSetDataLayout(M: ModuleRef, Triple: *const c_char);
-
-    /// Target triple. See Module::getTargetTriple.
-    pub fn LLVMGetTarget(M: ModuleRef) -> *const c_char;
-    pub fn LLVMSetTarget(M: ModuleRef, Triple: *const c_char);
-
-    /// See Module::dump.
-    pub fn LLVMDumpModule(M: ModuleRef);
-
-    /// See Module::setModuleInlineAsm.
-    pub fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *const c_char);
-
-    /// See llvm::LLVMTypeKind::getTypeID.
-    pub fn LLVMGetTypeKind(Ty: TypeRef) -> TypeKind;
-
-    /// See llvm::LLVMType::getContext.
-    pub fn LLVMGetTypeContext(Ty: TypeRef) -> ContextRef;
-
-    /* Operations on integer types */
-    pub fn LLVMInt1TypeInContext(C: ContextRef) -> TypeRef;
-    pub fn LLVMInt8TypeInContext(C: ContextRef) -> TypeRef;
-    pub fn LLVMInt16TypeInContext(C: ContextRef) -> TypeRef;
-    pub fn LLVMInt32TypeInContext(C: ContextRef) -> TypeRef;
-    pub fn LLVMInt64TypeInContext(C: ContextRef) -> TypeRef;
-    pub fn LLVMIntTypeInContext(C: ContextRef, NumBits: c_uint)
-                                -> TypeRef;
-
-    pub fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint;
-
-    /* Operations on real types */
-    pub fn LLVMFloatTypeInContext(C: ContextRef) -> TypeRef;
-    pub fn LLVMDoubleTypeInContext(C: ContextRef) -> TypeRef;
-    pub fn LLVMX86FP80TypeInContext(C: ContextRef) -> TypeRef;
-    pub fn LLVMFP128TypeInContext(C: ContextRef) -> TypeRef;
-    pub fn LLVMPPCFP128TypeInContext(C: ContextRef) -> TypeRef;
-
-    /* Operations on function types */
-    pub fn LLVMFunctionType(ReturnType: TypeRef,
-                            ParamTypes: *const TypeRef,
-                            ParamCount: c_uint,
-                            IsVarArg: Bool)
-                            -> TypeRef;
-    pub fn LLVMIsFunctionVarArg(FunctionTy: TypeRef) -> Bool;
-    pub fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef;
-    pub fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint;
-    pub fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *mut TypeRef);
-
-    /* Operations on struct types */
-    pub fn LLVMStructTypeInContext(C: ContextRef,
-                                   ElementTypes: *const TypeRef,
-                                   ElementCount: c_uint,
-                                   Packed: Bool)
-                                   -> TypeRef;
-    pub fn LLVMCountStructElementTypes(StructTy: TypeRef) -> c_uint;
-    pub fn LLVMGetStructElementTypes(StructTy: TypeRef,
-                                     Dest: *mut TypeRef);
-    pub fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool;
-
-    /* Operations on array, pointer, and vector types (sequence types) */
-    pub fn LLVMRustArrayType(ElementType: TypeRef, ElementCount: u64) -> TypeRef;
-    pub fn LLVMPointerType(ElementType: TypeRef, AddressSpace: c_uint)
-                           -> TypeRef;
-    pub fn LLVMVectorType(ElementType: TypeRef, ElementCount: c_uint)
-                          -> TypeRef;
-
-    pub fn LLVMGetElementType(Ty: TypeRef) -> TypeRef;
-    pub fn LLVMGetArrayLength(ArrayTy: TypeRef) -> c_uint;
-    pub fn LLVMGetPointerAddressSpace(PointerTy: TypeRef) -> c_uint;
-    pub fn LLVMGetPointerToGlobal(EE: ExecutionEngineRef, V: ValueRef)
-                                  -> *const c_void;
-    pub fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint;
-
-    /* Operations on other types */
-    pub fn LLVMVoidTypeInContext(C: ContextRef) -> TypeRef;
-    pub fn LLVMLabelTypeInContext(C: ContextRef) -> TypeRef;
-    pub fn LLVMMetadataTypeInContext(C: ContextRef) -> TypeRef;
-
-    /* Operations on all values */
-    pub fn LLVMTypeOf(Val: ValueRef) -> TypeRef;
-    pub fn LLVMGetValueName(Val: ValueRef) -> *const c_char;
-    pub fn LLVMSetValueName(Val: ValueRef, Name: *const c_char);
-    pub fn LLVMDumpValue(Val: ValueRef);
-    pub fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef);
-    pub fn LLVMHasMetadata(Val: ValueRef) -> c_int;
-    pub fn LLVMGetMetadata(Val: ValueRef, KindID: c_uint) -> ValueRef;
-    pub fn LLVMSetMetadata(Val: ValueRef, KindID: c_uint, Node: ValueRef);
-
-    /* Operations on Uses */
-    pub fn LLVMGetFirstUse(Val: ValueRef) -> UseRef;
-    pub fn LLVMGetNextUse(U: UseRef) -> UseRef;
-    pub fn LLVMGetUser(U: UseRef) -> ValueRef;
-    pub fn LLVMGetUsedValue(U: UseRef) -> ValueRef;
-
-    /* Operations on Users */
-    pub fn LLVMGetNumOperands(Val: ValueRef) -> c_int;
-    pub fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
-    pub fn LLVMSetOperand(Val: ValueRef, Index: c_uint, Op: ValueRef);
-
-    /* Operations on constants of any type */
-    pub fn LLVMConstNull(Ty: TypeRef) -> ValueRef;
-    /* all zeroes */
-    pub fn LLVMConstAllOnes(Ty: TypeRef) -> ValueRef;
-    pub fn LLVMConstICmp(Pred: c_ushort, V1: ValueRef, V2: ValueRef)
-                         -> ValueRef;
-    pub fn LLVMConstFCmp(Pred: c_ushort, V1: ValueRef, V2: ValueRef)
-                         -> ValueRef;
-    /* only for isize/vector */
-    pub fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;
-    pub fn LLVMIsConstant(Val: ValueRef) -> Bool;
-    pub fn LLVMIsNull(Val: ValueRef) -> Bool;
-    pub fn LLVMIsUndef(Val: ValueRef) -> Bool;
-    pub fn LLVMConstPointerNull(Ty: TypeRef) -> ValueRef;
-
-    /* Operations on metadata */
-    pub fn LLVMMDStringInContext(C: ContextRef,
-                                 Str: *const c_char,
-                                 SLen: c_uint)
-                                 -> ValueRef;
-    pub fn LLVMMDNodeInContext(C: ContextRef,
-                               Vals: *const ValueRef,
-                               Count: c_uint)
-                               -> ValueRef;
-    pub fn LLVMAddNamedMetadataOperand(M: ModuleRef,
-                                       Str: *const c_char,
-                                       Val: ValueRef);
-
-    /* Operations on scalar constants */
-    pub fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool)
-                        -> ValueRef;
-    pub fn LLVMConstIntOfString(IntTy: TypeRef, Text: *const c_char, Radix: u8)
-                                -> ValueRef;
-    pub fn LLVMConstIntOfStringAndSize(IntTy: TypeRef,
-                                       Text: *const c_char,
-                                       SLen: c_uint,
-                                       Radix: u8)
-                                       -> ValueRef;
-    pub fn LLVMConstReal(RealTy: TypeRef, N: f64) -> ValueRef;
-    pub fn LLVMConstRealOfString(RealTy: TypeRef, Text: *const c_char)
-                                 -> ValueRef;
-    pub fn LLVMConstRealOfStringAndSize(RealTy: TypeRef,
-                                        Text: *const c_char,
-                                        SLen: c_uint)
-                                        -> ValueRef;
-    pub fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
-    pub fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
-
-
-    /* Operations on composite constants */
-    pub fn LLVMConstStringInContext(C: ContextRef,
-                                    Str: *const c_char,
-                                    Length: c_uint,
-                                    DontNullTerminate: Bool)
-                                    -> ValueRef;
-    pub fn LLVMConstStructInContext(C: ContextRef,
-                                    ConstantVals: *const ValueRef,
-                                    Count: c_uint,
-                                    Packed: Bool)
-                                    -> ValueRef;
-
-    pub fn LLVMConstArray(ElementTy: TypeRef,
-                          ConstantVals: *const ValueRef,
-                          Length: c_uint)
-                          -> ValueRef;
-    pub fn LLVMConstVector(ScalarConstantVals: *const ValueRef, Size: c_uint)
-                           -> ValueRef;
-
-    /* Constant expressions */
-    pub fn LLVMAlignOf(Ty: TypeRef) -> ValueRef;
-    pub fn LLVMSizeOf(Ty: TypeRef) -> ValueRef;
-    pub fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef;
-    pub fn LLVMConstNSWNeg(ConstantVal: ValueRef) -> ValueRef;
-    pub fn LLVMConstNUWNeg(ConstantVal: ValueRef) -> ValueRef;
-    pub fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef;
-    pub fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef;
-    pub fn LLVMConstAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                        -> ValueRef;
-    pub fn LLVMConstNSWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                           -> ValueRef;
-    pub fn LLVMConstNUWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                           -> ValueRef;
-    pub fn LLVMConstFAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                         -> ValueRef;
-    pub fn LLVMConstSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                        -> ValueRef;
-    pub fn LLVMConstNSWSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                           -> ValueRef;
-    pub fn LLVMConstNUWSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                           -> ValueRef;
-    pub fn LLVMConstFSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                         -> ValueRef;
-    pub fn LLVMConstMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                        -> ValueRef;
-    pub fn LLVMConstNSWMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                           -> ValueRef;
-    pub fn LLVMConstNUWMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                           -> ValueRef;
-    pub fn LLVMConstFMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                         -> ValueRef;
-    pub fn LLVMConstUDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                         -> ValueRef;
-    pub fn LLVMConstSDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                         -> ValueRef;
-    pub fn LLVMConstExactSDiv(LHSConstant: ValueRef,
-                              RHSConstant: ValueRef)
-                              -> ValueRef;
-    pub fn LLVMConstFDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                         -> ValueRef;
-    pub fn LLVMConstURem(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                         -> ValueRef;
-    pub fn LLVMConstSRem(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                         -> ValueRef;
-    pub fn LLVMConstFRem(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                         -> ValueRef;
-    pub fn LLVMConstAnd(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                        -> ValueRef;
-    pub fn LLVMConstOr(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                       -> ValueRef;
-    pub fn LLVMConstXor(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                        -> ValueRef;
-    pub fn LLVMConstShl(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                        -> ValueRef;
-    pub fn LLVMConstLShr(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                         -> ValueRef;
-    pub fn LLVMConstAShr(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                         -> ValueRef;
-    pub fn LLVMConstGEP(ConstantVal: ValueRef,
-                        ConstantIndices: *const ValueRef,
-                        NumIndices: c_uint)
-                        -> ValueRef;
-    pub fn LLVMConstInBoundsGEP(ConstantVal: ValueRef,
-                                ConstantIndices: *const ValueRef,
-                                NumIndices: c_uint)
-                                -> ValueRef;
-    pub fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: TypeRef)
-                          -> ValueRef;
-    pub fn LLVMConstSExt(ConstantVal: ValueRef, ToType: TypeRef)
-                         -> ValueRef;
-    pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: TypeRef)
-                         -> ValueRef;
-    pub fn LLVMConstFPTrunc(ConstantVal: ValueRef, ToType: TypeRef)
-                            -> ValueRef;
-    pub fn LLVMConstFPExt(ConstantVal: ValueRef, ToType: TypeRef)
-                          -> ValueRef;
-    pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: TypeRef)
-                           -> ValueRef;
-    pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: TypeRef)
-                           -> ValueRef;
-    pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: TypeRef)
-                           -> ValueRef;
-    pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: TypeRef)
-                           -> ValueRef;
-    pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: TypeRef)
-                             -> ValueRef;
-    pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: TypeRef)
-                             -> ValueRef;
-    pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: TypeRef)
-                            -> ValueRef;
-    pub fn LLVMConstZExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
-                                  -> ValueRef;
-    pub fn LLVMConstSExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
-                                  -> ValueRef;
-    pub fn LLVMConstTruncOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
-                                   -> ValueRef;
-    pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: TypeRef)
-                                -> ValueRef;
-    pub fn LLVMConstIntCast(ConstantVal: ValueRef,
-                            ToType: TypeRef,
-                            isSigned: Bool)
-                            -> ValueRef;
-    pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: TypeRef)
-                           -> ValueRef;
-    pub fn LLVMConstSelect(ConstantCondition: ValueRef,
-                           ConstantIfTrue: ValueRef,
-                           ConstantIfFalse: ValueRef)
-                           -> ValueRef;
-    pub fn LLVMConstExtractElement(VectorConstant: ValueRef,
-                                   IndexConstant: ValueRef)
-                                   -> ValueRef;
-    pub fn LLVMConstInsertElement(VectorConstant: ValueRef,
-                                  ElementValueConstant: ValueRef,
-                                  IndexConstant: ValueRef)
-                                  -> ValueRef;
-    pub fn LLVMConstShuffleVector(VectorAConstant: ValueRef,
-                                  VectorBConstant: ValueRef,
-                                  MaskConstant: ValueRef)
-                                  -> ValueRef;
-    pub fn LLVMConstExtractValue(AggConstant: ValueRef,
-                                 IdxList: *const c_uint,
-                                 NumIdx: c_uint)
-                                 -> ValueRef;
-    pub fn LLVMConstInsertValue(AggConstant: ValueRef,
-                                ElementValueConstant: ValueRef,
-                                IdxList: *const c_uint,
-                                NumIdx: c_uint)
-                                -> ValueRef;
-    pub fn LLVMConstInlineAsm(Ty: TypeRef,
-                              AsmString: *const c_char,
-                              Constraints: *const c_char,
-                              HasSideEffects: Bool,
-                              IsAlignStack: Bool)
-                              -> ValueRef;
-    pub fn LLVMBlockAddress(F: ValueRef, BB: BasicBlockRef) -> ValueRef;
-
-
-
-    /* Operations on global variables, functions, and aliases (globals) */
-    pub fn LLVMGetGlobalParent(Global: ValueRef) -> ModuleRef;
-    pub fn LLVMIsDeclaration(Global: ValueRef) -> Bool;
-    pub fn LLVMGetLinkage(Global: ValueRef) -> c_uint;
-    pub fn LLVMSetLinkage(Global: ValueRef, Link: c_uint);
-    pub fn LLVMGetSection(Global: ValueRef) -> *const c_char;
-    pub fn LLVMSetSection(Global: ValueRef, Section: *const c_char);
-    pub fn LLVMGetVisibility(Global: ValueRef) -> c_uint;
-    pub fn LLVMSetVisibility(Global: ValueRef, Viz: c_uint);
-    pub fn LLVMGetAlignment(Global: ValueRef) -> c_uint;
-    pub fn LLVMSetAlignment(Global: ValueRef, Bytes: c_uint);
-
-
-    /* Operations on global variables */
-    pub fn LLVMIsAGlobalVariable(GlobalVar: ValueRef) -> ValueRef;
-    pub fn LLVMAddGlobal(M: ModuleRef, Ty: TypeRef, Name: *const c_char)
-                         -> ValueRef;
-    pub fn LLVMAddGlobalInAddressSpace(M: ModuleRef,
-                                       Ty: TypeRef,
-                                       Name: *const c_char,
-                                       AddressSpace: c_uint)
-                                       -> ValueRef;
-    pub fn LLVMGetNamedGlobal(M: ModuleRef, Name: *const c_char) -> ValueRef;
-    pub fn LLVMGetOrInsertGlobal(M: ModuleRef, Name: *const c_char, T: TypeRef) -> ValueRef;
-    pub fn LLVMGetFirstGlobal(M: ModuleRef) -> ValueRef;
-    pub fn LLVMGetLastGlobal(M: ModuleRef) -> ValueRef;
-    pub fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef;
-    pub fn LLVMGetPreviousGlobal(GlobalVar: ValueRef) -> ValueRef;
-    pub fn LLVMDeleteGlobal(GlobalVar: ValueRef);
-    pub fn LLVMGetInitializer(GlobalVar: ValueRef) -> ValueRef;
-    pub fn LLVMSetInitializer(GlobalVar: ValueRef,
-                              ConstantVal: ValueRef);
-    pub fn LLVMIsThreadLocal(GlobalVar: ValueRef) -> Bool;
-    pub fn LLVMSetThreadLocal(GlobalVar: ValueRef, IsThreadLocal: Bool);
-    pub fn LLVMIsGlobalConstant(GlobalVar: ValueRef) -> Bool;
-    pub fn LLVMSetGlobalConstant(GlobalVar: ValueRef, IsConstant: Bool);
-    pub fn LLVMGetNamedValue(M: ModuleRef, Name: *const c_char) -> ValueRef;
-
-    /* Operations on aliases */
-    pub fn LLVMAddAlias(M: ModuleRef,
-                        Ty: TypeRef,
-                        Aliasee: ValueRef,
-                        Name: *const c_char)
-                        -> ValueRef;
-
-    /* Operations on functions */
-    pub fn LLVMAddFunction(M: ModuleRef,
-                           Name: *const c_char,
-                           FunctionTy: TypeRef)
-                           -> ValueRef;
-    pub fn LLVMGetNamedFunction(M: ModuleRef, Name: *const c_char) -> ValueRef;
-    pub fn LLVMGetFirstFunction(M: ModuleRef) -> ValueRef;
-    pub fn LLVMGetLastFunction(M: ModuleRef) -> ValueRef;
-    pub fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef;
-    pub fn LLVMGetPreviousFunction(Fn: ValueRef) -> ValueRef;
-    pub fn LLVMDeleteFunction(Fn: ValueRef);
-    pub fn LLVMGetOrInsertFunction(M: ModuleRef,
-                                   Name: *const c_char,
-                                   FunctionTy: TypeRef)
-                                   -> ValueRef;
-    pub fn LLVMGetIntrinsicID(Fn: ValueRef) -> c_uint;
-    pub fn LLVMGetFunctionCallConv(Fn: ValueRef) -> c_uint;
-    pub fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
-    pub fn LLVMGetGC(Fn: ValueRef) -> *const c_char;
-    pub fn LLVMSetGC(Fn: ValueRef, Name: *const c_char);
-    pub fn LLVMAddDereferenceableAttr(Fn: ValueRef, index: c_uint, bytes: uint64_t);
-    pub fn LLVMAddFunctionAttribute(Fn: ValueRef, index: c_uint, PA: uint64_t);
-    pub fn LLVMAddFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
-    pub fn LLVMAddFunctionAttrStringValue(Fn: ValueRef, index: c_uint,
-                                          Name: *const c_char,
-                                          Value: *const c_char);
-    pub fn LLVMRemoveFunctionAttributes(Fn: ValueRef, index: c_uint, attr: uint64_t);
-    pub fn LLVMRemoveFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
-    pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_uint;
-    pub fn LLVMRemoveFunctionAttr(Fn: ValueRef, val: c_uint);
-
-    /* Operations on parameters */
-    pub fn LLVMCountParams(Fn: ValueRef) -> c_uint;
-    pub fn LLVMGetParams(Fn: ValueRef, Params: *const ValueRef);
-    pub fn LLVMGetParam(Fn: ValueRef, Index: c_uint) -> ValueRef;
-    pub fn LLVMGetParamParent(Inst: ValueRef) -> ValueRef;
-    pub fn LLVMGetFirstParam(Fn: ValueRef) -> ValueRef;
-    pub fn LLVMGetLastParam(Fn: ValueRef) -> ValueRef;
-    pub fn LLVMGetNextParam(Arg: ValueRef) -> ValueRef;
-    pub fn LLVMGetPreviousParam(Arg: ValueRef) -> ValueRef;
-    pub fn LLVMAddAttribute(Arg: ValueRef, PA: c_uint);
-    pub fn LLVMRemoveAttribute(Arg: ValueRef, PA: c_uint);
-    pub fn LLVMGetAttribute(Arg: ValueRef) -> c_uint;
-    pub fn LLVMSetParamAlignment(Arg: ValueRef, align: c_uint);
-
-    /* Operations on basic blocks */
-    pub fn LLVMBasicBlockAsValue(BB: BasicBlockRef) -> ValueRef;
-    pub fn LLVMValueIsBasicBlock(Val: ValueRef) -> Bool;
-    pub fn LLVMValueAsBasicBlock(Val: ValueRef) -> BasicBlockRef;
-    pub fn LLVMGetBasicBlockParent(BB: BasicBlockRef) -> ValueRef;
-    pub fn LLVMCountBasicBlocks(Fn: ValueRef) -> c_uint;
-    pub fn LLVMGetBasicBlocks(Fn: ValueRef, BasicBlocks: *const ValueRef);
-    pub fn LLVMGetFirstBasicBlock(Fn: ValueRef) -> BasicBlockRef;
-    pub fn LLVMGetLastBasicBlock(Fn: ValueRef) -> BasicBlockRef;
-    pub fn LLVMGetNextBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
-    pub fn LLVMGetPreviousBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
-    pub fn LLVMGetEntryBasicBlock(Fn: ValueRef) -> BasicBlockRef;
-
-    pub fn LLVMAppendBasicBlockInContext(C: ContextRef,
-                                         Fn: ValueRef,
-                                         Name: *const c_char)
-                                         -> BasicBlockRef;
-    pub fn LLVMInsertBasicBlockInContext(C: ContextRef,
-                                         BB: BasicBlockRef,
-                                         Name: *const c_char)
-                                         -> BasicBlockRef;
-    pub fn LLVMDeleteBasicBlock(BB: BasicBlockRef);
-
-    pub fn LLVMMoveBasicBlockAfter(BB: BasicBlockRef,
-                                   MoveAfter: BasicBlockRef);
-
-    pub fn LLVMMoveBasicBlockBefore(BB: BasicBlockRef,
-                                    MoveBefore: BasicBlockRef);
-
-    /* Operations on instructions */
-    pub fn LLVMGetInstructionParent(Inst: ValueRef) -> BasicBlockRef;
-    pub fn LLVMGetFirstInstruction(BB: BasicBlockRef) -> ValueRef;
-    pub fn LLVMGetLastInstruction(BB: BasicBlockRef) -> ValueRef;
-    pub fn LLVMGetNextInstruction(Inst: ValueRef) -> ValueRef;
-    pub fn LLVMGetPreviousInstruction(Inst: ValueRef) -> ValueRef;
-    pub fn LLVMInstructionEraseFromParent(Inst: ValueRef);
-
-    /* Operations on call sites */
-    pub fn LLVMSetInstructionCallConv(Instr: ValueRef, CC: c_uint);
-    pub fn LLVMGetInstructionCallConv(Instr: ValueRef) -> c_uint;
-    pub fn LLVMAddInstrAttribute(Instr: ValueRef,
-                                 index: c_uint,
-                                 IA: c_uint);
-    pub fn LLVMRemoveInstrAttribute(Instr: ValueRef,
-                                    index: c_uint,
-                                    IA: c_uint);
-    pub fn LLVMSetInstrParamAlignment(Instr: ValueRef,
-                                      index: c_uint,
-                                      align: c_uint);
-    pub fn LLVMRustAddCallSiteAttribute(Instr: ValueRef,
-                                    index: c_uint,
-                                    Val: uint64_t);
-    pub fn LLVMAddDereferenceableCallSiteAttr(Instr: ValueRef,
-                                              index: c_uint,
-                                              bytes: uint64_t);
-
-    /* Operations on call instructions (only) */
-    pub fn LLVMIsTailCall(CallInst: ValueRef) -> Bool;
-    pub fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool);
-
-    /* Operations on load/store instructions (only) */
-    pub fn LLVMGetVolatile(MemoryAccessInst: ValueRef) -> Bool;
-    pub fn LLVMSetVolatile(MemoryAccessInst: ValueRef, volatile: Bool);
-
-    /* Operations on phi nodes */
-    pub fn LLVMAddIncoming(PhiNode: ValueRef,
-                           IncomingValues: *const ValueRef,
-                           IncomingBlocks: *const BasicBlockRef,
-                           Count: c_uint);
-    pub fn LLVMCountIncoming(PhiNode: ValueRef) -> c_uint;
-    pub fn LLVMGetIncomingValue(PhiNode: ValueRef, Index: c_uint)
-                                -> ValueRef;
-    pub fn LLVMGetIncomingBlock(PhiNode: ValueRef, Index: c_uint)
-                                -> BasicBlockRef;
-
-    /* Instruction builders */
-    pub fn LLVMCreateBuilderInContext(C: ContextRef) -> BuilderRef;
-    pub fn LLVMPositionBuilder(Builder: BuilderRef,
-                               Block: BasicBlockRef,
-                               Instr: ValueRef);
-    pub fn LLVMPositionBuilderBefore(Builder: BuilderRef,
-                                     Instr: ValueRef);
-    pub fn LLVMPositionBuilderAtEnd(Builder: BuilderRef,
-                                    Block: BasicBlockRef);
-    pub fn LLVMGetInsertBlock(Builder: BuilderRef) -> BasicBlockRef;
-    pub fn LLVMClearInsertionPosition(Builder: BuilderRef);
-    pub fn LLVMInsertIntoBuilder(Builder: BuilderRef, Instr: ValueRef);
-    pub fn LLVMInsertIntoBuilderWithName(Builder: BuilderRef,
-                                         Instr: ValueRef,
-                                         Name: *const c_char);
-    pub fn LLVMDisposeBuilder(Builder: BuilderRef);
-
-    /* Execution engine */
-    pub fn LLVMBuildExecutionEngine(Mod: ModuleRef) -> ExecutionEngineRef;
-    pub fn LLVMDisposeExecutionEngine(EE: ExecutionEngineRef);
-    pub fn LLVMExecutionEngineFinalizeObject(EE: ExecutionEngineRef);
-    pub fn LLVMRustLoadDynamicLibrary(path: *const c_char) -> Bool;
-    pub fn LLVMExecutionEngineAddModule(EE: ExecutionEngineRef, M: ModuleRef);
-    pub fn LLVMExecutionEngineRemoveModule(EE: ExecutionEngineRef, M: ModuleRef)
-                                           -> Bool;
-
-    /* Metadata */
-    pub fn LLVMSetCurrentDebugLocation(Builder: BuilderRef, L: ValueRef);
-    pub fn LLVMGetCurrentDebugLocation(Builder: BuilderRef) -> ValueRef;
-    pub fn LLVMSetInstDebugLocation(Builder: BuilderRef, Inst: ValueRef);
-
-    /* Terminators */
-    pub fn LLVMBuildRetVoid(B: BuilderRef) -> ValueRef;
-    pub fn LLVMBuildRet(B: BuilderRef, V: ValueRef) -> ValueRef;
-    pub fn LLVMBuildAggregateRet(B: BuilderRef,
-                                 RetVals: *const ValueRef,
-                                 N: c_uint)
-                                 -> ValueRef;
-    pub fn LLVMBuildBr(B: BuilderRef, Dest: BasicBlockRef) -> ValueRef;
-    pub fn LLVMBuildCondBr(B: BuilderRef,
-                           If: ValueRef,
-                           Then: BasicBlockRef,
-                           Else: BasicBlockRef)
-                           -> ValueRef;
-    pub fn LLVMBuildSwitch(B: BuilderRef,
-                           V: ValueRef,
-                           Else: BasicBlockRef,
-                           NumCases: c_uint)
-                           -> ValueRef;
-    pub fn LLVMBuildIndirectBr(B: BuilderRef,
-                               Addr: ValueRef,
-                               NumDests: c_uint)
-                               -> ValueRef;
-    pub fn LLVMRustBuildInvoke(B: BuilderRef,
-                               Fn: ValueRef,
-                               Args: *const ValueRef,
-                               NumArgs: c_uint,
-                               Then: BasicBlockRef,
-                               Catch: BasicBlockRef,
-                               Bundle: OperandBundleDefRef,
-                               Name: *const c_char)
-                               -> ValueRef;
-    pub fn LLVMRustBuildLandingPad(B: BuilderRef,
-                                   Ty: TypeRef,
-                                   PersFn: ValueRef,
-                                   NumClauses: c_uint,
-                                   Name: *const c_char,
-                                   F: ValueRef)
-                                   -> ValueRef;
-    pub fn LLVMBuildResume(B: BuilderRef, Exn: ValueRef) -> ValueRef;
-    pub fn LLVMBuildUnreachable(B: BuilderRef) -> ValueRef;
-
-    pub fn LLVMRustBuildCleanupPad(B: BuilderRef,
-                                   ParentPad: ValueRef,
-                                   ArgCnt: c_uint,
-                                   Args: *const ValueRef,
-                                   Name: *const c_char) -> ValueRef;
-    pub fn LLVMRustBuildCleanupRet(B: BuilderRef,
-                                   CleanupPad: ValueRef,
-                                   UnwindBB: BasicBlockRef) -> ValueRef;
-    pub fn LLVMRustBuildCatchPad(B: BuilderRef,
-                                 ParentPad: ValueRef,
-                                 ArgCnt: c_uint,
-                                 Args: *const ValueRef,
-                                 Name: *const c_char) -> ValueRef;
-    pub fn LLVMRustBuildCatchRet(B: BuilderRef,
-                                 Pad: ValueRef,
-                                 BB: BasicBlockRef) -> ValueRef;
-    pub fn LLVMRustBuildCatchSwitch(Builder: BuilderRef,
-                                    ParentPad: ValueRef,
-                                    BB: BasicBlockRef,
-                                    NumHandlers: c_uint,
-                                    Name: *const c_char) -> ValueRef;
-    pub fn LLVMRustAddHandler(CatchSwitch: ValueRef,
-                              Handler: BasicBlockRef);
-    pub fn LLVMRustSetPersonalityFn(B: BuilderRef, Pers: ValueRef);
-
-    /* Add a case to the switch instruction */
-    pub fn LLVMAddCase(Switch: ValueRef,
-                       OnVal: ValueRef,
-                       Dest: BasicBlockRef);
-
-    /* Add a destination to the indirectbr instruction */
-    pub fn LLVMAddDestination(IndirectBr: ValueRef, Dest: BasicBlockRef);
-
-    /* Add a clause to the landing pad instruction */
-    pub fn LLVMAddClause(LandingPad: ValueRef, ClauseVal: ValueRef);
-
-    /* Set the cleanup on a landing pad instruction */
-    pub fn LLVMSetCleanup(LandingPad: ValueRef, Val: Bool);
-
-    /* Arithmetic */
-    pub fn LLVMBuildAdd(B: BuilderRef,
-                        LHS: ValueRef,
-                        RHS: ValueRef,
-                        Name: *const c_char)
-                        -> ValueRef;
-    pub fn LLVMBuildNSWAdd(B: BuilderRef,
-                           LHS: ValueRef,
-                           RHS: ValueRef,
-                           Name: *const c_char)
-                           -> ValueRef;
-    pub fn LLVMBuildNUWAdd(B: BuilderRef,
-                           LHS: ValueRef,
-                           RHS: ValueRef,
-                           Name: *const c_char)
-                           -> ValueRef;
-    pub fn LLVMBuildFAdd(B: BuilderRef,
-                         LHS: ValueRef,
-                         RHS: ValueRef,
-                         Name: *const c_char)
-                         -> ValueRef;
-    pub fn LLVMBuildSub(B: BuilderRef,
-                        LHS: ValueRef,
-                        RHS: ValueRef,
-                        Name: *const c_char)
-                        -> ValueRef;
-    pub fn LLVMBuildNSWSub(B: BuilderRef,
-                           LHS: ValueRef,
-                           RHS: ValueRef,
-                           Name: *const c_char)
-                           -> ValueRef;
-    pub fn LLVMBuildNUWSub(B: BuilderRef,
-                           LHS: ValueRef,
-                           RHS: ValueRef,
-                           Name: *const c_char)
-                           -> ValueRef;
-    pub fn LLVMBuildFSub(B: BuilderRef,
-                         LHS: ValueRef,
-                         RHS: ValueRef,
-                         Name: *const c_char)
-                         -> ValueRef;
-    pub fn LLVMBuildMul(B: BuilderRef,
-                        LHS: ValueRef,
-                        RHS: ValueRef,
-                        Name: *const c_char)
-                        -> ValueRef;
-    pub fn LLVMBuildNSWMul(B: BuilderRef,
-                           LHS: ValueRef,
-                           RHS: ValueRef,
-                           Name: *const c_char)
-                           -> ValueRef;
-    pub fn LLVMBuildNUWMul(B: BuilderRef,
-                           LHS: ValueRef,
-                           RHS: ValueRef,
-                           Name: *const c_char)
-                           -> ValueRef;
-    pub fn LLVMBuildFMul(B: BuilderRef,
-                         LHS: ValueRef,
-                         RHS: ValueRef,
-                         Name: *const c_char)
-                         -> ValueRef;
-    pub fn LLVMBuildUDiv(B: BuilderRef,
-                         LHS: ValueRef,
-                         RHS: ValueRef,
-                         Name: *const c_char)
-                         -> ValueRef;
-    pub fn LLVMBuildSDiv(B: BuilderRef,
-                         LHS: ValueRef,
-                         RHS: ValueRef,
-                         Name: *const c_char)
-                         -> ValueRef;
-    pub fn LLVMBuildExactSDiv(B: BuilderRef,
-                              LHS: ValueRef,
-                              RHS: ValueRef,
-                              Name: *const c_char)
-                              -> ValueRef;
-    pub fn LLVMBuildFDiv(B: BuilderRef,
-                         LHS: ValueRef,
-                         RHS: ValueRef,
-                         Name: *const c_char)
-                         -> ValueRef;
-    pub fn LLVMBuildURem(B: BuilderRef,
-                         LHS: ValueRef,
-                         RHS: ValueRef,
-                         Name: *const c_char)
-                         -> ValueRef;
-    pub fn LLVMBuildSRem(B: BuilderRef,
-                         LHS: ValueRef,
-                         RHS: ValueRef,
-                         Name: *const c_char)
-                         -> ValueRef;
-    pub fn LLVMBuildFRem(B: BuilderRef,
-                         LHS: ValueRef,
-                         RHS: ValueRef,
-                         Name: *const c_char)
-                         -> ValueRef;
-    pub fn LLVMBuildShl(B: BuilderRef,
-                        LHS: ValueRef,
-                        RHS: ValueRef,
-                        Name: *const c_char)
-                        -> ValueRef;
-    pub fn LLVMBuildLShr(B: BuilderRef,
-                         LHS: ValueRef,
-                         RHS: ValueRef,
-                         Name: *const c_char)
-                         -> ValueRef;
-    pub fn LLVMBuildAShr(B: BuilderRef,
-                         LHS: ValueRef,
-                         RHS: ValueRef,
-                         Name: *const c_char)
-                         -> ValueRef;
-    pub fn LLVMBuildAnd(B: BuilderRef,
-                        LHS: ValueRef,
-                        RHS: ValueRef,
-                        Name: *const c_char)
-                        -> ValueRef;
-    pub fn LLVMBuildOr(B: BuilderRef,
-                       LHS: ValueRef,
-                       RHS: ValueRef,
-                       Name: *const c_char)
-                           -> ValueRef;
-    pub fn LLVMBuildXor(B: BuilderRef,
-                        LHS: ValueRef,
-                        RHS: ValueRef,
-                        Name: *const c_char)
-                        -> ValueRef;
-    pub fn LLVMBuildBinOp(B: BuilderRef,
-                          Op: Opcode,
-                          LHS: ValueRef,
-                          RHS: ValueRef,
-                          Name: *const c_char)
-                          -> ValueRef;
-    pub fn LLVMBuildNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
-                        -> ValueRef;
-    pub fn LLVMBuildNSWNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
-                           -> ValueRef;
-    pub fn LLVMBuildNUWNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
-                           -> ValueRef;
-    pub fn LLVMBuildFNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
-                         -> ValueRef;
-    pub fn LLVMBuildNot(B: BuilderRef, V: ValueRef, Name: *const c_char)
-                        -> ValueRef;
-    pub fn LLVMRustSetHasUnsafeAlgebra(Instr: ValueRef);
-
-    /* Memory */
-    pub fn LLVMBuildAlloca(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
-                           -> ValueRef;
-    pub fn LLVMBuildFree(B: BuilderRef, PointerVal: ValueRef) -> ValueRef;
-    pub fn LLVMBuildLoad(B: BuilderRef,
-                         PointerVal: ValueRef,
-                         Name: *const c_char)
-                         -> ValueRef;
-
-    pub fn LLVMBuildStore(B: BuilderRef, Val: ValueRef, Ptr: ValueRef)
-                          -> ValueRef;
-
-    pub fn LLVMBuildGEP(B: BuilderRef,
-                        Pointer: ValueRef,
-                        Indices: *const ValueRef,
-                        NumIndices: c_uint,
-                        Name: *const c_char)
-                        -> ValueRef;
-    pub fn LLVMBuildInBoundsGEP(B: BuilderRef,
-                                Pointer: ValueRef,
-                                Indices: *const ValueRef,
-                                NumIndices: c_uint,
-                                Name: *const c_char)
-                                -> ValueRef;
-    pub fn LLVMBuildStructGEP(B: BuilderRef,
-                              Pointer: ValueRef,
-                              Idx: c_uint,
-                              Name: *const c_char)
-                              -> ValueRef;
-    pub fn LLVMBuildGlobalString(B: BuilderRef,
-                                 Str: *const c_char,
-                                 Name: *const c_char)
-                                 -> ValueRef;
-    pub fn LLVMBuildGlobalStringPtr(B: BuilderRef,
-                                    Str: *const c_char,
-                                    Name: *const c_char)
-                                    -> ValueRef;
-
-    /* Casts */
-    pub fn LLVMBuildTrunc(B: BuilderRef,
-                          Val: ValueRef,
-                          DestTy: TypeRef,
-                          Name: *const c_char)
-                          -> ValueRef;
-    pub fn LLVMBuildZExt(B: BuilderRef,
-                         Val: ValueRef,
-                         DestTy: TypeRef,
-                         Name: *const c_char)
-                         -> ValueRef;
-    pub fn LLVMBuildSExt(B: BuilderRef,
-                         Val: ValueRef,
-                         DestTy: TypeRef,
-                         Name: *const c_char)
-                         -> ValueRef;
-    pub fn LLVMBuildFPToUI(B: BuilderRef,
-                           Val: ValueRef,
-                           DestTy: TypeRef,
-                           Name: *const c_char)
-                           -> ValueRef;
-    pub fn LLVMBuildFPToSI(B: BuilderRef,
-                           Val: ValueRef,
-                           DestTy: TypeRef,
-                           Name: *const c_char)
-                           -> ValueRef;
-    pub fn LLVMBuildUIToFP(B: BuilderRef,
-                           Val: ValueRef,
-                           DestTy: TypeRef,
-                           Name: *const c_char)
-                           -> ValueRef;
-    pub fn LLVMBuildSIToFP(B: BuilderRef,
-                           Val: ValueRef,
-                           DestTy: TypeRef,
-                           Name: *const c_char)
-                           -> ValueRef;
-    pub fn LLVMBuildFPTrunc(B: BuilderRef,
-                            Val: ValueRef,
-                            DestTy: TypeRef,
-                            Name: *const c_char)
-                            -> ValueRef;
-    pub fn LLVMBuildFPExt(B: BuilderRef,
-                          Val: ValueRef,
-                          DestTy: TypeRef,
-                          Name: *const c_char)
-                          -> ValueRef;
-    pub fn LLVMBuildPtrToInt(B: BuilderRef,
-                             Val: ValueRef,
-                             DestTy: TypeRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-    pub fn LLVMBuildIntToPtr(B: BuilderRef,
-                             Val: ValueRef,
-                             DestTy: TypeRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-    pub fn LLVMBuildBitCast(B: BuilderRef,
-                            Val: ValueRef,
-                            DestTy: TypeRef,
-                            Name: *const c_char)
-                            -> ValueRef;
-    pub fn LLVMBuildZExtOrBitCast(B: BuilderRef,
-                                  Val: ValueRef,
-                                  DestTy: TypeRef,
-                                  Name: *const c_char)
-                                  -> ValueRef;
-    pub fn LLVMBuildSExtOrBitCast(B: BuilderRef,
-                                  Val: ValueRef,
-                                  DestTy: TypeRef,
-                                  Name: *const c_char)
-                                  -> ValueRef;
-    pub fn LLVMBuildTruncOrBitCast(B: BuilderRef,
-                                   Val: ValueRef,
-                                   DestTy: TypeRef,
-                                   Name: *const c_char)
-                                   -> ValueRef;
-    pub fn LLVMBuildCast(B: BuilderRef,
-                         Op: Opcode,
-                         Val: ValueRef,
-                         DestTy: TypeRef,
-                         Name: *const c_char) -> ValueRef;
-    pub fn LLVMBuildPointerCast(B: BuilderRef,
-                                Val: ValueRef,
-                                DestTy: TypeRef,
-                                Name: *const c_char)
-                                -> ValueRef;
-    pub fn LLVMBuildIntCast(B: BuilderRef,
-                            Val: ValueRef,
-                            DestTy: TypeRef,
-                            Name: *const c_char)
-                            -> ValueRef;
-    pub fn LLVMBuildFPCast(B: BuilderRef,
-                           Val: ValueRef,
-                           DestTy: TypeRef,
-                           Name: *const c_char)
-                           -> ValueRef;
-
-    /* Comparisons */
-    pub fn LLVMBuildICmp(B: BuilderRef,
-                         Op: c_uint,
-                         LHS: ValueRef,
-                         RHS: ValueRef,
-                         Name: *const c_char)
-                         -> ValueRef;
-    pub fn LLVMBuildFCmp(B: BuilderRef,
-                         Op: c_uint,
-                         LHS: ValueRef,
-                         RHS: ValueRef,
-                         Name: *const c_char)
-                         -> ValueRef;
-
-    /* Miscellaneous instructions */
-    pub fn LLVMBuildPhi(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
-                        -> ValueRef;
-    pub fn LLVMRustBuildCall(B: BuilderRef,
-                             Fn: ValueRef,
-                             Args: *const ValueRef,
-                             NumArgs: c_uint,
-                             Bundle: OperandBundleDefRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-    pub fn LLVMBuildSelect(B: BuilderRef,
-                           If: ValueRef,
-                           Then: ValueRef,
-                           Else: ValueRef,
-                           Name: *const c_char)
-                           -> ValueRef;
-    pub fn LLVMBuildVAArg(B: BuilderRef,
-                          list: ValueRef,
-                          Ty: TypeRef,
-                          Name: *const c_char)
-                          -> ValueRef;
-    pub fn LLVMBuildExtractElement(B: BuilderRef,
-                                   VecVal: ValueRef,
-                                   Index: ValueRef,
-                                   Name: *const c_char)
-                                   -> ValueRef;
-    pub fn LLVMBuildInsertElement(B: BuilderRef,
-                                  VecVal: ValueRef,
-                                  EltVal: ValueRef,
-                                  Index: ValueRef,
-                                  Name: *const c_char)
-                                  -> ValueRef;
-    pub fn LLVMBuildShuffleVector(B: BuilderRef,
-                                  V1: ValueRef,
-                                  V2: ValueRef,
-                                  Mask: ValueRef,
-                                  Name: *const c_char)
-                                  -> ValueRef;
-    pub fn LLVMBuildExtractValue(B: BuilderRef,
-                                 AggVal: ValueRef,
-                                 Index: c_uint,
-                                 Name: *const c_char)
-                                 -> ValueRef;
-    pub fn LLVMBuildInsertValue(B: BuilderRef,
-                                AggVal: ValueRef,
-                                EltVal: ValueRef,
-                                Index: c_uint,
-                                Name: *const c_char)
-                                -> ValueRef;
-
-    pub fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef, Name: *const c_char)
-                           -> ValueRef;
-    pub fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *const c_char)
-                              -> ValueRef;
-    pub fn LLVMBuildPtrDiff(B: BuilderRef,
-                            LHS: ValueRef,
-                            RHS: ValueRef,
-                            Name: *const c_char)
-                            -> ValueRef;
-
-    /* Atomic Operations */
-    pub fn LLVMBuildAtomicLoad(B: BuilderRef,
-                               PointerVal: ValueRef,
-                               Name: *const c_char,
-                               Order: AtomicOrdering,
-                               Alignment: c_uint)
-                               -> ValueRef;
-
-    pub fn LLVMBuildAtomicStore(B: BuilderRef,
-                                Val: ValueRef,
-                                Ptr: ValueRef,
-                                Order: AtomicOrdering,
-                                Alignment: c_uint)
-                                -> ValueRef;
-
-    pub fn LLVMRustBuildAtomicCmpXchg(B: BuilderRef,
-                                  LHS: ValueRef,
-                                  CMP: ValueRef,
-                                  RHS: ValueRef,
-                                  Order: AtomicOrdering,
-                                  FailureOrder: AtomicOrdering,
-                                  Weak: Bool)
-                                  -> ValueRef;
-    pub fn LLVMBuildAtomicRMW(B: BuilderRef,
-                              Op: AtomicBinOp,
-                              LHS: ValueRef,
-                              RHS: ValueRef,
-                              Order: AtomicOrdering,
-                              SingleThreaded: Bool)
-                              -> ValueRef;
-
-    pub fn LLVMBuildAtomicFence(B: BuilderRef,
-                                Order: AtomicOrdering,
-                                Scope: SynchronizationScope);
-
-
-    /* Selected entries from the downcasts. */
-    pub fn LLVMIsATerminatorInst(Inst: ValueRef) -> ValueRef;
-    pub fn LLVMIsAStoreInst(Inst: ValueRef) -> ValueRef;
-
-    /// Writes a module to the specified path. Returns 0 on success.
-    pub fn LLVMWriteBitcodeToFile(M: ModuleRef, Path: *const c_char) -> c_int;
-
-    /// Creates target data from a target layout string.
-    pub fn LLVMCreateTargetData(StringRep: *const c_char) -> TargetDataRef;
-    /// Number of bytes clobbered when doing a Store to *T.
-    pub fn LLVMStoreSizeOfType(TD: TargetDataRef, Ty: TypeRef)
-                               -> c_ulonglong;
-
-    /// Number of bytes clobbered when doing a Store to *T.
-    pub fn LLVMSizeOfTypeInBits(TD: TargetDataRef, Ty: TypeRef)
-                                -> c_ulonglong;
-
-    /// Distance between successive elements in an array of T. Includes ABI padding.
-    pub fn LLVMABISizeOfType(TD: TargetDataRef, Ty: TypeRef) -> c_ulonglong;
-
-    /// Returns the preferred alignment of a type.
-    pub fn LLVMPreferredAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
-                                        -> c_uint;
-    /// Returns the minimum alignment of a type.
-    pub fn LLVMABIAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
-                                  -> c_uint;
-
-    /// Computes the byte offset of the indexed struct element for a
-    /// target.
-    pub fn LLVMOffsetOfElement(TD: TargetDataRef,
-                               StructTy: TypeRef,
-                               Element: c_uint)
-                               -> c_ulonglong;
-
-    /// Returns the minimum alignment of a type when part of a call frame.
-    pub fn LLVMCallFrameAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
-                                        -> c_uint;
-
-    /// Disposes target data.
-    pub fn LLVMDisposeTargetData(TD: TargetDataRef);
-
-    /// Creates a pass manager.
-    pub fn LLVMCreatePassManager() -> PassManagerRef;
-
-    /// Creates a function-by-function pass manager
-    pub fn LLVMCreateFunctionPassManagerForModule(M: ModuleRef)
-                                                  -> PassManagerRef;
-
-    /// Disposes a pass manager.
-    pub fn LLVMDisposePassManager(PM: PassManagerRef);
-
-    /// Runs a pass manager on a module.
-    pub fn LLVMRunPassManager(PM: PassManagerRef, M: ModuleRef) -> Bool;
-
-    /// Runs the function passes on the provided function.
-    pub fn LLVMRunFunctionPassManager(FPM: PassManagerRef, F: ValueRef)
-                                      -> Bool;
-
-    /// Initializes all the function passes scheduled in the manager
-    pub fn LLVMInitializeFunctionPassManager(FPM: PassManagerRef) -> Bool;
-
-    /// Finalizes all the function passes scheduled in the manager
-    pub fn LLVMFinalizeFunctionPassManager(FPM: PassManagerRef) -> Bool;
-
-    pub fn LLVMInitializePasses();
-
-    /// Adds a verification pass.
-    pub fn LLVMAddVerifierPass(PM: PassManagerRef);
-
-    pub fn LLVMAddGlobalOptimizerPass(PM: PassManagerRef);
-    pub fn LLVMAddIPSCCPPass(PM: PassManagerRef);
-    pub fn LLVMAddDeadArgEliminationPass(PM: PassManagerRef);
-    pub fn LLVMAddInstructionCombiningPass(PM: PassManagerRef);
-    pub fn LLVMAddCFGSimplificationPass(PM: PassManagerRef);
-    pub fn LLVMAddFunctionInliningPass(PM: PassManagerRef);
-    pub fn LLVMAddFunctionAttrsPass(PM: PassManagerRef);
-    pub fn LLVMAddScalarReplAggregatesPass(PM: PassManagerRef);
-    pub fn LLVMAddScalarReplAggregatesPassSSA(PM: PassManagerRef);
-    pub fn LLVMAddJumpThreadingPass(PM: PassManagerRef);
-    pub fn LLVMAddConstantPropagationPass(PM: PassManagerRef);
-    pub fn LLVMAddReassociatePass(PM: PassManagerRef);
-    pub fn LLVMAddLoopRotatePass(PM: PassManagerRef);
-    pub fn LLVMAddLICMPass(PM: PassManagerRef);
-    pub fn LLVMAddLoopUnswitchPass(PM: PassManagerRef);
-    pub fn LLVMAddLoopDeletionPass(PM: PassManagerRef);
-    pub fn LLVMAddLoopUnrollPass(PM: PassManagerRef);
-    pub fn LLVMAddGVNPass(PM: PassManagerRef);
-    pub fn LLVMAddMemCpyOptPass(PM: PassManagerRef);
-    pub fn LLVMAddSCCPPass(PM: PassManagerRef);
-    pub fn LLVMAddDeadStoreEliminationPass(PM: PassManagerRef);
-    pub fn LLVMAddStripDeadPrototypesPass(PM: PassManagerRef);
-    pub fn LLVMAddConstantMergePass(PM: PassManagerRef);
-    pub fn LLVMAddArgumentPromotionPass(PM: PassManagerRef);
-    pub fn LLVMAddTailCallEliminationPass(PM: PassManagerRef);
-    pub fn LLVMAddIndVarSimplifyPass(PM: PassManagerRef);
-    pub fn LLVMAddAggressiveDCEPass(PM: PassManagerRef);
-    pub fn LLVMAddGlobalDCEPass(PM: PassManagerRef);
-    pub fn LLVMAddCorrelatedValuePropagationPass(PM: PassManagerRef);
-    pub fn LLVMAddPruneEHPass(PM: PassManagerRef);
-    pub fn LLVMAddSimplifyLibCallsPass(PM: PassManagerRef);
-    pub fn LLVMAddLoopIdiomPass(PM: PassManagerRef);
-    pub fn LLVMAddEarlyCSEPass(PM: PassManagerRef);
-    pub fn LLVMAddTypeBasedAliasAnalysisPass(PM: PassManagerRef);
-    pub fn LLVMAddBasicAliasAnalysisPass(PM: PassManagerRef);
-
-    pub fn LLVMPassManagerBuilderCreate() -> PassManagerBuilderRef;
-    pub fn LLVMPassManagerBuilderDispose(PMB: PassManagerBuilderRef);
-    pub fn LLVMPassManagerBuilderSetOptLevel(PMB: PassManagerBuilderRef,
-                                             OptimizationLevel: c_uint);
-    pub fn LLVMPassManagerBuilderSetSizeLevel(PMB: PassManagerBuilderRef,
-                                              Value: Bool);
-    pub fn LLVMPassManagerBuilderSetDisableUnitAtATime(
-        PMB: PassManagerBuilderRef,
-        Value: Bool);
-    pub fn LLVMPassManagerBuilderSetDisableUnrollLoops(
-        PMB: PassManagerBuilderRef,
-        Value: Bool);
-    pub fn LLVMPassManagerBuilderSetDisableSimplifyLibCalls(
-        PMB: PassManagerBuilderRef,
-        Value: Bool);
-    pub fn LLVMPassManagerBuilderUseInlinerWithThreshold(
-        PMB: PassManagerBuilderRef,
-        threshold: c_uint);
-    pub fn LLVMPassManagerBuilderPopulateModulePassManager(
-        PMB: PassManagerBuilderRef,
-        PM: PassManagerRef);
-
-    pub fn LLVMPassManagerBuilderPopulateFunctionPassManager(
-        PMB: PassManagerBuilderRef,
-        PM: PassManagerRef);
-    pub fn LLVMPassManagerBuilderPopulateLTOPassManager(
-        PMB: PassManagerBuilderRef,
-        PM: PassManagerRef,
-        Internalize: Bool,
-        RunInliner: Bool);
-
-    /// Destroys a memory buffer.
-    pub fn LLVMDisposeMemoryBuffer(MemBuf: MemoryBufferRef);
-
-
-    /* Stuff that's in rustllvm/ because it's not upstream yet. */
-
-    /// Opens an object file.
-    pub fn LLVMCreateObjectFile(MemBuf: MemoryBufferRef) -> ObjectFileRef;
-    /// Closes an object file.
-    pub fn LLVMDisposeObjectFile(ObjFile: ObjectFileRef);
-
-    /// Enumerates the sections in an object file.
-    pub fn LLVMGetSections(ObjFile: ObjectFileRef) -> SectionIteratorRef;
-    /// Destroys a section iterator.
-    pub fn LLVMDisposeSectionIterator(SI: SectionIteratorRef);
-    /// Returns true if the section iterator is at the end of the section
-    /// list:
-    pub fn LLVMIsSectionIteratorAtEnd(ObjFile: ObjectFileRef,
-                                      SI: SectionIteratorRef)
-                                      -> Bool;
-    /// Moves the section iterator to point to the next section.
-    pub fn LLVMMoveToNextSection(SI: SectionIteratorRef);
-    /// Returns the current section size.
-    pub fn LLVMGetSectionSize(SI: SectionIteratorRef) -> c_ulonglong;
-    /// Returns the current section contents as a string buffer.
-    pub fn LLVMGetSectionContents(SI: SectionIteratorRef) -> *const c_char;
-
-    /// Reads the given file and returns it as a memory buffer. Use
-    /// LLVMDisposeMemoryBuffer() to get rid of it.
-    pub fn LLVMRustCreateMemoryBufferWithContentsOfFile(Path: *const c_char)
-                                                        -> MemoryBufferRef;
-    /// Borrows the contents of the memory buffer (doesn't copy it)
-    pub fn LLVMCreateMemoryBufferWithMemoryRange(InputData: *const c_char,
-                                                 InputDataLength: size_t,
-                                                 BufferName: *const c_char,
-                                                 RequiresNull: Bool)
-                                                 -> MemoryBufferRef;
-    pub fn LLVMCreateMemoryBufferWithMemoryRangeCopy(InputData: *const c_char,
-                                                     InputDataLength: size_t,
-                                                     BufferName: *const c_char)
-                                                     -> MemoryBufferRef;
-
-    pub fn LLVMIsMultithreaded() -> Bool;
-    pub fn LLVMStartMultithreaded() -> Bool;
-
-    /// Returns a string describing the last error caused by an LLVMRust* call.
-    pub fn LLVMRustGetLastError() -> *const c_char;
-
-    /// Print the pass timings since static dtors aren't picking them up.
-    pub fn LLVMRustPrintPassTimings();
-
-    pub fn LLVMStructCreateNamed(C: ContextRef, Name: *const c_char) -> TypeRef;
-
-    pub fn LLVMStructSetBody(StructTy: TypeRef,
-                             ElementTypes: *const TypeRef,
-                             ElementCount: c_uint,
-                             Packed: Bool);
-
-    pub fn LLVMConstNamedStruct(S: TypeRef,
-                                ConstantVals: *const ValueRef,
-                                Count: c_uint)
-                                -> ValueRef;
-
-    /// Enables LLVM debug output.
-    pub fn LLVMSetDebug(Enabled: c_int);
-
-    /// Prepares inline assembly.
-    pub fn LLVMInlineAsm(Ty: TypeRef,
-                         AsmString: *const c_char,
-                         Constraints: *const c_char,
-                         SideEffects: Bool,
-                         AlignStack: Bool,
-                         Dialect: c_uint)
-                         -> ValueRef;
-
-    pub fn LLVMRustDebugMetadataVersion() -> u32;
-    pub fn LLVMVersionMajor() -> u32;
-    pub fn LLVMVersionMinor() -> u32;
-
-    pub fn LLVMRustAddModuleFlag(M: ModuleRef,
-                                 name: *const c_char,
-                                 value: u32);
-
-    pub fn LLVMDIBuilderCreate(M: ModuleRef) -> DIBuilderRef;
-
-    pub fn LLVMDIBuilderDispose(Builder: DIBuilderRef);
-
-    pub fn LLVMDIBuilderFinalize(Builder: DIBuilderRef);
-
-    pub fn LLVMDIBuilderCreateCompileUnit(Builder: DIBuilderRef,
-                                          Lang: c_uint,
-                                          File: *const c_char,
-                                          Dir: *const c_char,
-                                          Producer: *const c_char,
-                                          isOptimized: bool,
-                                          Flags: *const c_char,
-                                          RuntimeVer: c_uint,
-                                          SplitName: *const c_char)
-                                          -> DIDescriptor;
-
-    pub fn LLVMDIBuilderCreateFile(Builder: DIBuilderRef,
-                                   Filename: *const c_char,
-                                   Directory: *const c_char)
-                                   -> DIFile;
-
-    pub fn LLVMDIBuilderCreateSubroutineType(Builder: DIBuilderRef,
-                                             File: DIFile,
-                                             ParameterTypes: DIArray)
-                                             -> DICompositeType;
-
-    pub fn LLVMDIBuilderCreateFunction(Builder: DIBuilderRef,
-                                       Scope: DIDescriptor,
-                                       Name: *const c_char,
-                                       LinkageName: *const c_char,
-                                       File: DIFile,
-                                       LineNo: c_uint,
-                                       Ty: DIType,
-                                       isLocalToUnit: bool,
-                                       isDefinition: bool,
-                                       ScopeLine: c_uint,
-                                       Flags: c_uint,
-                                       isOptimized: bool,
-                                       Fn: ValueRef,
-                                       TParam: DIArray,
-                                       Decl: DIDescriptor)
-                                       -> DISubprogram;
-
-    pub fn LLVMDIBuilderCreateBasicType(Builder: DIBuilderRef,
-                                        Name: *const c_char,
-                                        SizeInBits: c_ulonglong,
-                                        AlignInBits: c_ulonglong,
-                                        Encoding: c_uint)
-                                        -> DIBasicType;
-
-    pub fn LLVMDIBuilderCreatePointerType(Builder: DIBuilderRef,
-                                          PointeeTy: DIType,
-                                          SizeInBits: c_ulonglong,
-                                          AlignInBits: c_ulonglong,
-                                          Name: *const c_char)
-                                          -> DIDerivedType;
-
-    pub fn LLVMDIBuilderCreateStructType(Builder: DIBuilderRef,
-                                         Scope: DIDescriptor,
-                                         Name: *const c_char,
-                                         File: DIFile,
-                                         LineNumber: c_uint,
-                                         SizeInBits: c_ulonglong,
-                                         AlignInBits: c_ulonglong,
-                                         Flags: c_uint,
-                                         DerivedFrom: DIType,
-                                         Elements: DIArray,
-                                         RunTimeLang: c_uint,
-                                         VTableHolder: DIType,
-                                         UniqueId: *const c_char)
-                                         -> DICompositeType;
-
-    pub fn LLVMDIBuilderCreateMemberType(Builder: DIBuilderRef,
-                                         Scope: DIDescriptor,
-                                         Name: *const c_char,
-                                         File: DIFile,
-                                         LineNo: c_uint,
-                                         SizeInBits: c_ulonglong,
-                                         AlignInBits: c_ulonglong,
-                                         OffsetInBits: c_ulonglong,
-                                         Flags: c_uint,
-                                         Ty: DIType)
-                                         -> DIDerivedType;
-
-    pub fn LLVMDIBuilderCreateLexicalBlock(Builder: DIBuilderRef,
-                                           Scope: DIScope,
-                                           File: DIFile,
-                                           Line: c_uint,
-                                           Col: c_uint)
-                                           -> DILexicalBlock;
-
-    pub fn LLVMDIBuilderCreateStaticVariable(Builder: DIBuilderRef,
-                                             Context: DIScope,
-                                             Name: *const c_char,
-                                             LinkageName: *const c_char,
-                                             File: DIFile,
-                                             LineNo: c_uint,
-                                             Ty: DIType,
-                                             isLocalToUnit: bool,
-                                             Val: ValueRef,
-                                             Decl: DIDescriptor)
-                                             -> DIGlobalVariable;
-
-    pub fn LLVMDIBuilderCreateVariable(Builder: DIBuilderRef,
-                                            Tag: c_uint,
-                                            Scope: DIDescriptor,
-                                            Name: *const c_char,
-                                            File: DIFile,
-                                            LineNo: c_uint,
-                                            Ty: DIType,
-                                            AlwaysPreserve: bool,
-                                            Flags: c_uint,
-                                            AddrOps: *const i64,
-                                            AddrOpsCount: c_uint,
-                                            ArgNo: c_uint)
-                                            -> DIVariable;
-
-    pub fn LLVMDIBuilderCreateArrayType(Builder: DIBuilderRef,
-                                        Size: c_ulonglong,
-                                        AlignInBits: c_ulonglong,
-                                        Ty: DIType,
-                                        Subscripts: DIArray)
-                                        -> DIType;
-
-    pub fn LLVMDIBuilderCreateVectorType(Builder: DIBuilderRef,
-                                         Size: c_ulonglong,
-                                         AlignInBits: c_ulonglong,
-                                         Ty: DIType,
-                                         Subscripts: DIArray)
-                                         -> DIType;
-
-    pub fn LLVMDIBuilderGetOrCreateSubrange(Builder: DIBuilderRef,
-                                            Lo: c_longlong,
-                                            Count: c_longlong)
-                                            -> DISubrange;
-
-    pub fn LLVMDIBuilderGetOrCreateArray(Builder: DIBuilderRef,
-                                         Ptr: *const DIDescriptor,
-                                         Count: c_uint)
-                                         -> DIArray;
-
-    pub fn LLVMDIBuilderInsertDeclareAtEnd(Builder: DIBuilderRef,
-                                           Val: ValueRef,
-                                           VarInfo: DIVariable,
-                                           AddrOps: *const i64,
-                                           AddrOpsCount: c_uint,
-                                           DL: ValueRef,
-                                           InsertAtEnd: BasicBlockRef)
-                                           -> ValueRef;
-
-    pub fn LLVMDIBuilderInsertDeclareBefore(Builder: DIBuilderRef,
-                                            Val: ValueRef,
-                                            VarInfo: DIVariable,
-                                            AddrOps: *const i64,
-                                            AddrOpsCount: c_uint,
-                                            DL: ValueRef,
-                                            InsertBefore: ValueRef)
-                                            -> ValueRef;
-
-    pub fn LLVMDIBuilderCreateEnumerator(Builder: DIBuilderRef,
-                                         Name: *const c_char,
-                                         Val: c_ulonglong)
-                                         -> DIEnumerator;
-
-    pub fn LLVMDIBuilderCreateEnumerationType(Builder: DIBuilderRef,
-                                              Scope: DIScope,
-                                              Name: *const c_char,
-                                              File: DIFile,
-                                              LineNumber: c_uint,
-                                              SizeInBits: c_ulonglong,
-                                              AlignInBits: c_ulonglong,
-                                              Elements: DIArray,
-                                              ClassType: DIType)
-                                              -> DIType;
-
-    pub fn LLVMDIBuilderCreateUnionType(Builder: DIBuilderRef,
-                                        Scope: DIScope,
-                                        Name: *const c_char,
-                                        File: DIFile,
-                                        LineNumber: c_uint,
-                                        SizeInBits: c_ulonglong,
-                                        AlignInBits: c_ulonglong,
-                                        Flags: c_uint,
-                                        Elements: DIArray,
-                                        RunTimeLang: c_uint,
-                                        UniqueId: *const c_char)
-                                        -> DIType;
-
-    pub fn LLVMSetUnnamedAddr(GlobalVar: ValueRef, UnnamedAddr: Bool);
-
-    pub fn LLVMDIBuilderCreateTemplateTypeParameter(Builder: DIBuilderRef,
-                                                    Scope: DIScope,
-                                                    Name: *const c_char,
-                                                    Ty: DIType,
-                                                    File: DIFile,
-                                                    LineNo: c_uint,
-                                                    ColumnNo: c_uint)
-                                                    -> DITemplateTypeParameter;
-
-    pub fn LLVMDIBuilderCreateOpDeref() -> i64;
-
-    pub fn LLVMDIBuilderCreateOpPlus() -> i64;
-
-    pub fn LLVMDIBuilderCreateNameSpace(Builder: DIBuilderRef,
-                                        Scope: DIScope,
-                                        Name: *const c_char,
-                                        File: DIFile,
-                                        LineNo: c_uint)
-                                        -> DINameSpace;
-
-    pub fn LLVMDIBuilderCreateDebugLocation(Context: ContextRef,
-                                            Line: c_uint,
-                                            Column: c_uint,
-                                            Scope: DIScope,
-                                            InlinedAt: MetadataRef)
-                                            -> ValueRef;
-
-    pub fn LLVMDICompositeTypeSetTypeArray(Builder: DIBuilderRef,
-                                           CompositeType: DIType,
-                                           TypeArray: DIArray);
-    pub fn LLVMWriteTypeToString(Type: TypeRef, s: RustStringRef);
-    pub fn LLVMWriteValueToString(value_ref: ValueRef, s: RustStringRef);
-
-    pub fn LLVMIsAArgument(value_ref: ValueRef) -> ValueRef;
-
-    pub fn LLVMIsAAllocaInst(value_ref: ValueRef) -> ValueRef;
-    pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef;
-
-    pub fn LLVMRustPassKind(Pass: PassRef) -> SupportedPassKind;
-    pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> PassRef;
-    pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: PassRef);
-
-    pub fn LLVMRustHasFeature(T: TargetMachineRef,
-                              s: *const c_char) -> bool;
-
-    pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
-                                       CPU: *const c_char,
-                                       Features: *const c_char,
-                                       Model: CodeGenModel,
-                                       Reloc: RelocMode,
-                                       Level: CodeGenOptLevel,
-                                       UseSoftFP: bool,
-                                       PositionIndependentExecutable: bool,
-                                       FunctionSections: bool,
-                                       DataSections: bool) -> TargetMachineRef;
-    pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef);
-    pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef,
-                                     PM: PassManagerRef,
-                                     M: ModuleRef);
-    pub fn LLVMRustAddBuilderLibraryInfo(PMB: PassManagerBuilderRef,
-                                         M: ModuleRef,
-                                         DisableSimplifyLibCalls: bool);
-    pub fn LLVMRustConfigurePassManagerBuilder(PMB: PassManagerBuilderRef,
-                                               OptLevel: CodeGenOptLevel,
-                                               MergeFunctions: bool,
-                                               SLPVectorize: bool,
-                                               LoopVectorize: bool);
-    pub fn LLVMRustAddLibraryInfo(PM: PassManagerRef, M: ModuleRef,
-                                  DisableSimplifyLibCalls: bool);
-    pub fn LLVMRustRunFunctionPassManager(PM: PassManagerRef, M: ModuleRef);
-    pub fn LLVMRustWriteOutputFile(T: TargetMachineRef,
-                                   PM: PassManagerRef,
-                                   M: ModuleRef,
-                                   Output: *const c_char,
-                                   FileType: FileType) -> bool;
-    pub fn LLVMRustPrintModule(PM: PassManagerRef,
-                               M: ModuleRef,
-                               Output: *const c_char);
-    pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char);
-    pub fn LLVMRustPrintPasses();
-    pub fn LLVMRustSetNormalizedTarget(M: ModuleRef, triple: *const c_char);
-    pub fn LLVMRustAddAlwaysInlinePass(P: PassManagerBuilderRef,
-                                       AddLifetimes: bool);
-    pub fn LLVMRustLinkInExternalBitcode(M: ModuleRef,
-                                         bc: *const c_char,
-                                         len: size_t) -> bool;
-    pub fn LLVMRustRunRestrictionPass(M: ModuleRef,
-                                      syms: *const *const c_char,
-                                      len: size_t);
-    pub fn LLVMRustMarkAllFunctionsNounwind(M: ModuleRef);
-
-    pub fn LLVMRustOpenArchive(path: *const c_char) -> ArchiveRef;
-    pub fn LLVMRustArchiveIteratorNew(AR: ArchiveRef) -> ArchiveIteratorRef;
-    pub fn LLVMRustArchiveIteratorNext(AIR: ArchiveIteratorRef) -> ArchiveChildRef;
-    pub fn LLVMRustArchiveChildName(ACR: ArchiveChildRef,
-                                    size: *mut size_t) -> *const c_char;
-    pub fn LLVMRustArchiveChildData(ACR: ArchiveChildRef,
-                                    size: *mut size_t) -> *const c_char;
-    pub fn LLVMRustArchiveChildFree(ACR: ArchiveChildRef);
-    pub fn LLVMRustArchiveIteratorFree(AIR: ArchiveIteratorRef);
-    pub fn LLVMRustDestroyArchive(AR: ArchiveRef);
-
-    pub fn LLVMRustSetDLLStorageClass(V: ValueRef,
-                                      C: DLLStorageClassTypes);
-
-    pub fn LLVMRustGetSectionName(SI: SectionIteratorRef,
-                                  data: *mut *const c_char) -> c_int;
-
-    pub fn LLVMWriteTwineToString(T: TwineRef, s: RustStringRef);
-
-    pub fn LLVMContextSetDiagnosticHandler(C: ContextRef,
-                                           Handler: DiagnosticHandler,
-                                           DiagnosticContext: *mut c_void);
-
-    pub fn LLVMUnpackOptimizationDiagnostic(DI: DiagnosticInfoRef,
-                                            pass_name_out: *mut *const c_char,
-                                            function_out: *mut ValueRef,
-                                            debugloc_out: *mut DebugLocRef,
-                                            message_out: *mut TwineRef);
-    pub fn LLVMUnpackInlineAsmDiagnostic(DI: DiagnosticInfoRef,
-                                            cookie_out: *mut c_uint,
-                                            message_out: *mut TwineRef,
-                                            instruction_out: *mut ValueRef);
-
-    pub fn LLVMWriteDiagnosticInfoToString(DI: DiagnosticInfoRef, s: RustStringRef);
-    pub fn LLVMGetDiagInfoSeverity(DI: DiagnosticInfoRef) -> DiagnosticSeverity;
-    pub fn LLVMGetDiagInfoKind(DI: DiagnosticInfoRef) -> DiagnosticKind;
-
-    pub fn LLVMWriteDebugLocToString(C: ContextRef, DL: DebugLocRef, s: RustStringRef);
-
-    pub fn LLVMSetInlineAsmDiagnosticHandler(C: ContextRef,
-                                             H: InlineAsmDiagHandler,
-                                             CX: *mut c_void);
-
-    pub fn LLVMWriteSMDiagnosticToString(d: SMDiagnosticRef, s: RustStringRef);
-
-    pub fn LLVMRustWriteArchive(Dst: *const c_char,
-                                NumMembers: size_t,
-                                Members: *const RustArchiveMemberRef,
-                                WriteSymbtab: bool,
-                                Kind: ArchiveKind) -> c_int;
-    pub fn LLVMRustArchiveMemberNew(Filename: *const c_char,
-                                    Name: *const c_char,
-                                    Child: ArchiveChildRef) -> RustArchiveMemberRef;
-    pub fn LLVMRustArchiveMemberFree(Member: RustArchiveMemberRef);
-
-    pub fn LLVMRustSetDataLayoutFromTargetMachine(M: ModuleRef,
-                                                  TM: TargetMachineRef);
-    pub fn LLVMRustGetModuleDataLayout(M: ModuleRef) -> TargetDataRef;
-
-    pub fn LLVMRustBuildOperandBundleDef(Name: *const c_char,
-                                         Inputs: *const ValueRef,
-                                         NumInputs: c_uint)
-                                         -> OperandBundleDefRef;
-    pub fn LLVMRustFreeOperandBundleDef(Bundle: OperandBundleDefRef);
+pub enum RustString_opaque {}
+pub type RustStringRef = *mut RustString_opaque;
+type RustStringRepr = *mut RefCell<Vec<u8>>;
 
-    pub fn LLVMRustPositionBuilderAtStart(B: BuilderRef, BB: BasicBlockRef);
+/// Appending to a Rust string -- used by raw_rust_string_ostream.
+#[no_mangle]
+pub unsafe extern "C" fn rust_llvm_string_write_impl(sr: RustStringRef,
+                                                     ptr: *const c_char,
+                                                     size: size_t) {
+    let slice = slice::from_raw_parts(ptr as *const u8, size as usize);
 
-    pub fn LLVMRustSetComdat(M: ModuleRef, V: ValueRef, Name: *const c_char);
-    pub fn LLVMRustUnsetComdat(V: ValueRef);
-    pub fn LLVMRustSetModulePIELevel(M: ModuleRef);
+    let sr = sr as RustStringRepr;
+    (*sr).borrow_mut().extend_from_slice(slice);
 }
 
-// LLVM requires symbols from this library, but apparently they're not printed
-// during llvm-config?
-#[cfg(windows)]
-#[link(name = "ole32")]
-extern {}
-
 pub fn SetInstructionCallConv(instr: ValueRef, cc: CallConv) {
     unsafe {
         LLVMSetInstructionCallConv(instr, cc as c_uint);
@@ -2171,11 +200,6 @@ pub fn SetFunctionCallConv(fn_: ValueRef, cc: CallConv) {
         LLVMSetFunctionCallConv(fn_, cc as c_uint);
     }
 }
-pub fn SetLinkage(global: ValueRef, link: Linkage) {
-    unsafe {
-        LLVMSetLinkage(global, link as c_uint);
-    }
-}
 
 // Externally visible symbols that might appear in multiple translation units need to appear in
 // their own comdat section so that the duplicates can be discarded at link time. This can for
@@ -2195,12 +219,6 @@ pub fn UnsetComdat(val: ValueRef) {
     }
 }
 
-pub fn SetDLLStorageClass(global: ValueRef, class: DLLStorageClassTypes) {
-    unsafe {
-        LLVMRustSetDLLStorageClass(global, class);
-    }
-}
-
 pub fn SetUnnamedAddr(global: ValueRef, unnamed: bool) {
     unsafe {
         LLVMSetUnnamedAddr(global, unnamed as Bool);
@@ -2213,29 +231,40 @@ pub fn set_thread_local(global: ValueRef, is_thread_local: bool) {
     }
 }
 
-pub fn ConstICmp(pred: IntPredicate, v1: ValueRef, v2: ValueRef) -> ValueRef {
-    unsafe {
-        LLVMConstICmp(pred as c_ushort, v1, v2)
+impl Attribute {
+    pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
+        unsafe {
+            LLVMRustAddFunctionAttribute(
+                llfn, idx.as_uint(), self.bits())
+        }
     }
-}
-pub fn ConstFCmp(pred: RealPredicate, v1: ValueRef, v2: ValueRef) -> ValueRef {
-    unsafe {
-        LLVMConstFCmp(pred as c_ushort, v1, v2)
+
+    pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
+        unsafe {
+            LLVMRustAddCallSiteAttribute(
+                callsite, idx.as_uint(), self.bits())
+        }
     }
-}
 
-pub fn SetFunctionAttribute(fn_: ValueRef, attr: Attribute) {
-    unsafe {
-        LLVMAddFunctionAttribute(fn_, FunctionIndex as c_uint,
-                                 attr.bits() as uint64_t)
+    pub fn unapply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
+        unsafe {
+            LLVMRustRemoveFunctionAttributes(
+                llfn, idx.as_uint(), self.bits())
+        }
     }
-}
 
-pub fn RemoveFunctionAttributes(fn_: ValueRef, attr: Attribute) {
-    unsafe {
-        LLVMRemoveFunctionAttributes(fn_, FunctionIndex as c_uint,
-                                           attr.bits() as uint64_t)
+    pub fn toggle_llfn(&self,
+                       idx: AttributePlace,
+                       llfn: ValueRef,
+                       set: bool)
+    {
+        if set {
+            self.apply_llfn(idx, llfn);
+        } else {
+            self.unapply_llfn(idx, llfn);
+        }
     }
+
 }
 
 /* Memory-managed interface to target data. */
@@ -2332,22 +361,6 @@ pub fn get_params(llfn: ValueRef) -> Vec<ValueRef> {
     }
 }
 
-#[allow(missing_copy_implementations)]
-pub enum RustString_opaque {}
-pub type RustStringRef = *mut RustString_opaque;
-type RustStringRepr = *mut RefCell<Vec<u8>>;
-
-/// Appending to a Rust string -- used by raw_rust_string_ostream.
-#[no_mangle]
-pub unsafe extern "C" fn rust_llvm_string_write_impl(sr: RustStringRef,
-                                                     ptr: *const c_char,
-                                                     size: size_t) {
-    let slice = slice::from_raw_parts(ptr as *const u8, size as usize);
-
-    let sr = sr as RustStringRepr;
-    (*sr).borrow_mut().extend_from_slice(slice);
-}
-
 pub fn build_string<F>(f: F) -> Option<String> where F: FnOnce(RustStringRef){
     let mut buf = RefCell::new(Vec::new());
     f(&mut buf as RustStringRepr as RustStringRef);
@@ -2355,12 +368,12 @@ pub fn build_string<F>(f: F) -> Option<String> where F: FnOnce(RustStringRef){
 }
 
 pub unsafe fn twine_to_string(tr: TwineRef) -> String {
-    build_string(|s| LLVMWriteTwineToString(tr, s))
+    build_string(|s| LLVMRustWriteTwineToString(tr, s))
         .expect("got a non-UTF8 Twine from LLVM")
 }
 
 pub unsafe fn debug_loc_to_string(c: ContextRef, tr: DebugLocRef) -> String {
-    build_string(|s| LLVMWriteDebugLocToString(c, tr, s))
+    build_string(|s| LLVMRustWriteDebugLocToString(c, tr, s))
         .expect("got a non-UTF8 DebugLoc from LLVM")
 }
 
diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs
new file mode 100644 (file)
index 0000000..fccd4a6
--- /dev/null
@@ -0,0 +1,116 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use rustc::ty::TyCtxt;
+use rustc::mir::repr::*;
+use rustc::mir::transform::{MirPass, MirSource, Pass};
+use rustc_data_structures::indexed_vec::Idx;
+use rustc::ty::VariantKind;
+
+pub struct Deaggregator;
+
+impl Pass for Deaggregator {}
+
+impl<'tcx> MirPass<'tcx> for Deaggregator {
+    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                    source: MirSource, mir: &mut Mir<'tcx>) {
+        let node_id = source.item_id();
+        let node_path = tcx.item_path_str(tcx.map.local_def_id(node_id));
+        debug!("running on: {:?}", node_path);
+        // we only run when mir_opt_level > 1
+        match tcx.sess.opts.debugging_opts.mir_opt_level {
+            Some(0) |
+            Some(1) |
+            None => { return; },
+            _ => {}
+        };
+
+        // Do not trigger on constants.  Could be revised in future
+        if let MirSource::Fn(_) = source {} else { return; }
+        // In fact, we might not want to trigger in other cases.
+        // Ex: when we could use SROA.  See issue #35259
+
+        let mut curr: usize = 0;
+        for bb in mir.basic_blocks_mut() {
+            let idx = match get_aggregate_statement(curr, &bb.statements) {
+                Some(idx) => idx,
+                None => continue,
+            };
+            // do the replacement
+            debug!("removing statement {:?}", idx);
+            let src_info = bb.statements[idx].source_info;
+            let suffix_stmts = bb.statements.split_off(idx+1);
+            let orig_stmt = bb.statements.pop().unwrap();
+            let StatementKind::Assign(ref lhs, ref rhs) = orig_stmt.kind;
+            let (agg_kind, operands) = match rhs {
+                &Rvalue::Aggregate(ref agg_kind, ref operands) => (agg_kind, operands),
+                _ => span_bug!(src_info.span, "expected aggregate, not {:?}", rhs),
+            };
+            let (adt_def, variant, substs) = match agg_kind {
+                &AggregateKind::Adt(adt_def, variant, substs) => (adt_def, variant, substs),
+                _ => span_bug!(src_info.span, "expected struct, not {:?}", rhs),
+            };
+            let n = bb.statements.len();
+            bb.statements.reserve(n + operands.len() + suffix_stmts.len());
+            for (i, op) in operands.iter().enumerate() {
+                let ref variant_def = adt_def.variants[variant];
+                let ty = variant_def.fields[i].ty(tcx, substs);
+                let rhs = Rvalue::Use(op.clone());
+
+                // since we don't handle enums, we don't need a cast
+                let lhs_cast = lhs.clone();
+
+                // FIXME we cannot deaggregate enums issue: #35186
+
+                let lhs_proj = Lvalue::Projection(Box::new(LvalueProjection {
+                    base: lhs_cast,
+                    elem: ProjectionElem::Field(Field::new(i), ty),
+                }));
+                let new_statement = Statement {
+                    source_info: src_info,
+                    kind: StatementKind::Assign(lhs_proj, rhs),
+                };
+                debug!("inserting: {:?} @ {:?}", new_statement, idx + i);
+                bb.statements.push(new_statement);
+            }
+            curr = bb.statements.len();
+            bb.statements.extend(suffix_stmts);
+        }
+    }
+}
+
+fn get_aggregate_statement<'a, 'tcx, 'b>(curr: usize,
+                                         statements: &Vec<Statement<'tcx>>)
+                                         -> Option<usize> {
+    for i in curr..statements.len() {
+        let ref statement = statements[i];
+        let StatementKind::Assign(_, ref rhs) = statement.kind;
+        let (kind, operands) = match rhs {
+            &Rvalue::Aggregate(ref kind, ref operands) => (kind, operands),
+            _ => continue,
+        };
+        let (adt_def, variant) = match kind {
+            &AggregateKind::Adt(adt_def, variant, _) => (adt_def, variant),
+            _ => continue,
+        };
+        if operands.len() == 0 || adt_def.variants.len() > 1 {
+            // don't deaggregate ()
+            // don't deaggregate enums ... for now
+            continue;
+        }
+        debug!("getting variant {:?}", variant);
+        debug!("for adt_def {:?}", adt_def);
+        let variant_def = &adt_def.variants[variant];
+        if variant_def.kind == VariantKind::Struct {
+            return Some(i);
+        }
+    };
+    None
+}
index 7b707b4adb69ac2aa2a7499a505948c5bb41565e..c3485b8256da1fa0c8b1178309f5b978faf9f615 100644 (file)
@@ -17,3 +17,4 @@
 pub mod promote_consts;
 pub mod qualify_consts;
 pub mod dump_mir;
+pub mod deaggregator;
index 28204f4630c83501aff590f10f2dbd2d73ccdd05..b16ee9577463bc53958219e406fe1c0e45e0c219 100644 (file)
@@ -687,8 +687,10 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>) {
             Rvalue::Box(_) => {
                 self.add(Qualif::NOT_CONST);
                 if self.mode != Mode::Fn {
-                    span_err!(self.tcx.sess, self.span, E0010,
-                              "allocations are not allowed in {}s", self.mode);
+                    struct_span_err!(self.tcx.sess, self.span, E0010,
+                                     "allocations are not allowed in {}s", self.mode)
+                        .span_label(self.span, &format!("allocation not allowed in {}s", self.mode))
+                        .emit();
                 }
             }
 
index a90b563515eae0e89b2159430200d7cbe03991b9..91d2500564fd3b7d246f406fcb8d117fb0fede0b 100644 (file)
@@ -38,16 +38,18 @@ fn check_label(&self, label: Ident, span: Span, id: NodeId) {
             self.err_handler().span_err(span, &format!("invalid label name `{}`", label.name));
         }
         if label.name.as_str() == "'_" {
-            self.session.add_lint(
-                lint::builtin::LIFETIME_UNDERSCORE, id, span,
-                format!("invalid label name `{}`", label.name)
-            );
+            self.session.add_lint(lint::builtin::LIFETIME_UNDERSCORE,
+                                  id,
+                                  span,
+                                  format!("invalid label name `{}`", label.name));
         }
     }
 
     fn invalid_visibility(&self, vis: &Visibility, span: Span, note: Option<&str>) {
         if vis != &Visibility::Inherited {
-            let mut err = struct_span_err!(self.session, span, E0449,
+            let mut err = struct_span_err!(self.session,
+                                           span,
+                                           E0449,
                                            "unnecessary visibility qualifier");
             if let Some(note) = note {
                 err.span_note(span, note);
@@ -55,15 +57,26 @@ fn invalid_visibility(&self, vis: &Visibility, span: Span, note: Option<&str>) {
             err.emit();
         }
     }
+
+    fn check_decl_no_pat<ReportFn: Fn(Span, bool)>(&self, decl: &FnDecl, report_err: ReportFn) {
+        for arg in &decl.inputs {
+            match arg.pat.node {
+                PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), _, None) |
+                PatKind::Wild => {}
+                PatKind::Ident(..) => report_err(arg.pat.span, true),
+                _ => report_err(arg.pat.span, false),
+            }
+        }
+    }
 }
 
 impl<'a> Visitor for AstValidator<'a> {
     fn visit_lifetime(&mut self, lt: &Lifetime) {
         if lt.name.as_str() == "'_" {
-            self.session.add_lint(
-                lint::builtin::LIFETIME_UNDERSCORE, lt.id, lt.span,
-                format!("invalid lifetime name `{}`", lt.name)
-            );
+            self.session.add_lint(lint::builtin::LIFETIME_UNDERSCORE,
+                                  lt.id,
+                                  lt.span,
+                                  format!("invalid lifetime name `{}`", lt.name));
         }
 
         visit::walk_lifetime(self, lt)
@@ -71,9 +84,12 @@ fn visit_lifetime(&mut self, lt: &Lifetime) {
 
     fn visit_expr(&mut self, expr: &Expr) {
         match expr.node {
-            ExprKind::While(_, _, Some(ident)) | ExprKind::Loop(_, Some(ident)) |
-            ExprKind::WhileLet(_, _, _, Some(ident)) | ExprKind::ForLoop(_, _, _, Some(ident)) |
-            ExprKind::Break(Some(ident)) | ExprKind::Continue(Some(ident)) => {
+            ExprKind::While(_, _, Some(ident)) |
+            ExprKind::Loop(_, Some(ident)) |
+            ExprKind::WhileLet(_, _, _, Some(ident)) |
+            ExprKind::ForLoop(_, _, _, Some(ident)) |
+            ExprKind::Break(Some(ident)) |
+            ExprKind::Continue(Some(ident)) => {
                 self.check_label(ident.node, ident.span, expr.id);
             }
             _ => {}
@@ -82,14 +98,34 @@ fn visit_expr(&mut self, expr: &Expr) {
         visit::walk_expr(self, expr)
     }
 
+    fn visit_ty(&mut self, ty: &Ty) {
+        match ty.node {
+            TyKind::BareFn(ref bfty) => {
+                self.check_decl_no_pat(&bfty.decl, |span, _| {
+                    let mut err = struct_span_err!(self.session,
+                                                   span,
+                                                   E0561,
+                                                   "patterns aren't allowed in function pointer \
+                                                    types");
+                    err.span_note(span,
+                                  "this is a recent error, see issue #35203 for more details");
+                    err.emit();
+                });
+            }
+            _ => {}
+        }
+
+        visit::walk_ty(self, ty)
+    }
+
     fn visit_path(&mut self, path: &Path, id: NodeId) {
         if path.global && path.segments.len() > 0 {
             let ident = path.segments[0].identifier;
             if token::Ident(ident).is_path_segment_keyword() {
-                self.session.add_lint(
-                    lint::builtin::SUPER_OR_SELF_IN_GLOBAL_PATH, id, path.span,
-                    format!("global paths cannot start with `{}`", ident)
-                );
+                self.session.add_lint(lint::builtin::SUPER_OR_SELF_IN_GLOBAL_PATH,
+                                      id,
+                                      path.span,
+                                      format!("global paths cannot start with `{}`", ident));
             }
         }
 
@@ -101,8 +137,8 @@ fn visit_item(&mut self, item: &Item) {
             ItemKind::Use(ref view_path) => {
                 let path = view_path.node.path();
                 if !path.segments.iter().all(|segment| segment.parameters.is_empty()) {
-                    self.err_handler().span_err(path.span, "type or lifetime parameters \
-                                                            in import path");
+                    self.err_handler()
+                        .span_err(path.span, "type or lifetime parameters in import path");
                 }
             }
             ItemKind::Impl(_, _, _, Some(..), _, ref impl_items) => {
@@ -112,15 +148,18 @@ fn visit_item(&mut self, item: &Item) {
                 }
             }
             ItemKind::Impl(_, _, _, None, _, _) => {
-                self.invalid_visibility(&item.vis, item.span, Some("place qualifiers on individual \
-                                                                    impl items instead"));
+                self.invalid_visibility(&item.vis,
+                                        item.span,
+                                        Some("place qualifiers on individual impl items instead"));
             }
             ItemKind::DefaultImpl(..) => {
                 self.invalid_visibility(&item.vis, item.span, None);
             }
             ItemKind::ForeignMod(..) => {
-                self.invalid_visibility(&item.vis, item.span, Some("place qualifiers on individual \
-                                                                    foreign items instead"));
+                self.invalid_visibility(&item.vis,
+                                        item.span,
+                                        Some("place qualifiers on individual foreign items \
+                                              instead"));
             }
             ItemKind::Enum(ref def, _) => {
                 for variant in &def.variants {
@@ -135,16 +174,43 @@ fn visit_item(&mut self, item: &Item) {
         visit::walk_item(self, item)
     }
 
-    fn visit_variant_data(&mut self, vdata: &VariantData, _: Ident,
-                          _: &Generics, _: NodeId, span: Span) {
+    fn visit_foreign_item(&mut self, fi: &ForeignItem) {
+        match fi.node {
+            ForeignItemKind::Fn(ref decl, _) => {
+                self.check_decl_no_pat(decl, |span, is_recent| {
+                    let mut err = struct_span_err!(self.session,
+                                                   span,
+                                                   E0130,
+                                                   "patterns aren't allowed in foreign function \
+                                                    declarations");
+                    if is_recent {
+                        err.span_note(span,
+                                      "this is a recent error, see issue #35203 for more details");
+                    }
+                    err.emit();
+                });
+            }
+            ForeignItemKind::Static(..) => {}
+        }
+
+        visit::walk_foreign_item(self, fi)
+    }
+
+    fn visit_variant_data(&mut self,
+                          vdata: &VariantData,
+                          _: Ident,
+                          _: &Generics,
+                          _: NodeId,
+                          span: Span) {
         if vdata.fields().is_empty() {
             if vdata.is_tuple() {
-                self.err_handler().struct_span_err(span, "empty tuple structs and enum variants \
-                                                          are not allowed, use unit structs and \
-                                                          enum variants instead")
-                                         .span_help(span, "remove trailing `()` to make a unit \
-                                                           struct or unit enum variant")
-                                         .emit();
+                self.err_handler()
+                    .struct_span_err(span,
+                                     "empty tuple structs and enum variants are not allowed, use \
+                                      unit structs and enum variants instead")
+                    .span_help(span,
+                               "remove trailing `()` to make a unit struct or unit enum variant")
+                    .emit();
             }
         }
 
@@ -153,10 +219,10 @@ struct or unit enum variant")
 
     fn visit_vis(&mut self, vis: &Visibility) {
         match *vis {
-            Visibility::Restricted{ref path, ..} => {
+            Visibility::Restricted { ref path, .. } => {
                 if !path.segments.iter().all(|segment| segment.parameters.is_empty()) {
-                    self.err_handler().span_err(path.span, "type or lifetime parameters \
-                                                            in visibility path");
+                    self.err_handler()
+                        .span_err(path.span, "type or lifetime parameters in visibility path");
                 }
             }
             _ => {}
index 1030a4b0116de5a07572ffa53fa974d909f4b6b7..fc55118c9f4c518ed0fa989067cf40f95f580f9e 100644 (file)
@@ -25,7 +25,7 @@
 // by borrowck::gather_loans
 
 use rustc::dep_graph::DepNode;
-use rustc::ty::cast::{CastKind};
+use rustc::ty::cast::CastKind;
 use rustc_const_eval::{ConstEvalErr, lookup_const_fn_by_id, compare_lit_exprs};
 use rustc_const_eval::{eval_const_expr_partial, lookup_const_by_id};
 use rustc_const_eval::ErrKind::{IndexOpFeatureGated, UnimplementedConstVal, MiscCatchAll, Math};
@@ -71,12 +71,12 @@ struct CheckCrateVisitor<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     mode: Mode,
     qualif: ConstQualif,
-    rvalue_borrows: NodeMap<hir::Mutability>
+    rvalue_borrows: NodeMap<hir::Mutability>,
 }
 
 impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
-    fn with_mode<F, R>(&mut self, mode: Mode, f: F) -> R where
-        F: FnOnce(&mut CheckCrateVisitor<'a, 'gcx>) -> R,
+    fn with_mode<F, R>(&mut self, mode: Mode, f: F) -> R
+        where F: FnOnce(&mut CheckCrateVisitor<'a, 'gcx>) -> R
     {
         let (old_mode, old_qualif) = (self.mode, self.qualif);
         self.mode = mode;
@@ -87,17 +87,17 @@ fn with_mode<F, R>(&mut self, mode: Mode, f: F) -> R where
         r
     }
 
-    fn with_euv<F, R>(&mut self, item_id: Option<ast::NodeId>, f: F) -> R where
-        F: for<'b, 'tcx> FnOnce(&mut euv::ExprUseVisitor<'b, 'gcx, 'tcx>) -> R,
+    fn with_euv<F, R>(&mut self, item_id: Option<ast::NodeId>, f: F) -> R
+        where F: for<'b, 'tcx> FnOnce(&mut euv::ExprUseVisitor<'b, 'gcx, 'tcx>) -> R
     {
         let param_env = match item_id {
             Some(item_id) => ty::ParameterEnvironment::for_item(self.tcx, item_id),
-            None => self.tcx.empty_parameter_environment()
+            None => self.tcx.empty_parameter_environment(),
         };
 
-        self.tcx.infer_ctxt(None, Some(param_env), ProjectionMode::AnyFinal).enter(|infcx| {
-            f(&mut euv::ExprUseVisitor::new(self, &infcx))
-        })
+        self.tcx
+            .infer_ctxt(None, Some(param_env), ProjectionMode::AnyFinal)
+            .enter(|infcx| f(&mut euv::ExprUseVisitor::new(self, &infcx)))
     }
 
     fn global_expr(&mut self, mode: Mode, expr: &hir::Expr) -> ConstQualif {
@@ -111,13 +111,17 @@ fn global_expr(&mut self, mode: Mode, expr: &hir::Expr) -> ConstQualif {
         }
         if let Err(err) = eval_const_expr_partial(self.tcx, expr, ExprTypeChecked, None) {
             match err.kind {
-                UnimplementedConstVal(_) => {},
-                IndexOpFeatureGated => {},
-                ErroneousReferencedConstant(_) => {},
-                _ => self.tcx.sess.add_lint(CONST_ERR, expr.id, expr.span,
-                                         format!("constant evaluation error: {}. This will \
-                                                 become a HARD ERROR in the future",
-                                                 err.description().into_oneline())),
+                UnimplementedConstVal(_) => {}
+                IndexOpFeatureGated => {}
+                ErroneousReferencedConstant(_) => {}
+                _ => {
+                    self.tcx.sess.add_lint(CONST_ERR,
+                                           expr.id,
+                                           expr.span,
+                                           format!("constant evaluation error: {}. This will \
+                                                    become a HARD ERROR in the future",
+                                                   err.description().into_oneline()))
+                }
             }
         }
         self.with_mode(mode, |this| {
@@ -143,9 +147,7 @@ fn fn_like(&mut self,
         }
 
         let mode = match fk {
-            FnKind::ItemFn(_, _, _, hir::Constness::Const, _, _, _) => {
-                Mode::ConstFn
-            }
+            FnKind::ItemFn(_, _, _, hir::Constness::Const, _, _, _) => Mode::ConstFn,
             FnKind::Method(_, m, _, _) => {
                 if m.constness == hir::Constness::Const {
                     Mode::ConstFn
@@ -153,7 +155,7 @@ fn fn_like(&mut self,
                     Mode::Var
                 }
             }
-            _ => Mode::Var
+            _ => Mode::Var,
         };
 
         let qualif = self.with_mode(mode, |this| {
@@ -175,11 +177,7 @@ fn add_qualif(&mut self, qualif: ConstQualif) {
     }
 
     /// Returns true if the call is to a const fn or method.
-    fn handle_const_fn_call(&mut self,
-                            _expr: &hir::Expr,
-                            def_id: DefId,
-                            ret_ty: Ty<'gcx>)
-                            -> bool {
+    fn handle_const_fn_call(&mut self, _expr: &hir::Expr, def_id: DefId, ret_ty: Ty<'gcx>) -> bool {
         if let Some(fn_like) = lookup_const_fn_by_id(self.tcx, def_id) {
             let qualif = self.fn_like(fn_like.kind(),
                                       fn_like.decl(),
@@ -285,13 +283,15 @@ fn visit_pat(&mut self, p: &hir::Pat) {
                     Ok(Ordering::Less) |
                     Ok(Ordering::Equal) => {}
                     Ok(Ordering::Greater) => {
-                        span_err!(self.tcx.sess, start.span, E0030,
-                            "lower range bound must be less than or equal to upper");
+                        span_err!(self.tcx.sess,
+                                  start.span,
+                                  E0030,
+                                  "lower range bound must be less than or equal to upper");
                     }
                     Err(ErrorReported) => {}
                 }
             }
-            _ => intravisit::walk_pat(self, p)
+            _ => intravisit::walk_pat(self, p),
         }
     }
 
@@ -301,13 +301,13 @@ fn visit_block(&mut self, block: &hir::Block) {
             match stmt.node {
                 hir::StmtDecl(ref decl, _) => {
                     match decl.node {
-                        hir::DeclLocal(_) => {},
+                        hir::DeclLocal(_) => {}
                         // Item statements are allowed
-                        hir::DeclItem(_) => continue
+                        hir::DeclItem(_) => continue,
                     }
                 }
-                hir::StmtExpr(_, _) => {},
-                hir::StmtSemi(_, _) => {},
+                hir::StmtExpr(_, _) => {}
+                hir::StmtSemi(_, _) => {}
             }
             self.add_qualif(ConstQualif::NOT_CONST);
         }
@@ -340,7 +340,7 @@ fn visit_expr(&mut self, ex: &hir::Expr) {
                 // The count is checked elsewhere (typeck).
                 let count = match node_ty.sty {
                     ty::TyArray(_, n) => n,
-                    _ => bug!()
+                    _ => bug!(),
                 };
                 // [element; 0] is always zero-sized.
                 if count == 0 {
@@ -354,7 +354,8 @@ fn visit_expr(&mut self, ex: &hir::Expr) {
                 for pat in arms.iter().flat_map(|arm| &arm.pats) {
                     let pat_borrow = self.rvalue_borrows.remove(&pat.id);
                     match (borrow, pat_borrow) {
-                        (None, _) | (_, Some(hir::MutMutable)) => {
+                        (None, _) |
+                        (_, Some(hir::MutMutable)) => {
                             borrow = pat_borrow;
                         }
                         _ => {}
@@ -365,7 +366,7 @@ fn visit_expr(&mut self, ex: &hir::Expr) {
                 }
                 intravisit::walk_expr(self, ex);
             }
-            _ => intravisit::walk_expr(self, ex)
+            _ => intravisit::walk_expr(self, ex),
         }
 
         // Handle borrows on (or inside the autorefs of) this expression.
@@ -405,17 +406,18 @@ fn visit_expr(&mut self, ex: &hir::Expr) {
         if self.mode == Mode::Var && !self.qualif.intersects(ConstQualif::NOT_CONST) {
             match eval_const_expr_partial(self.tcx, ex, ExprTypeChecked, None) {
                 Ok(_) => {}
-                Err(ConstEvalErr { kind: UnimplementedConstVal(_), ..}) |
-                Err(ConstEvalErr { kind: MiscCatchAll, ..}) |
-                Err(ConstEvalErr { kind: MiscBinaryOp, ..}) |
-                Err(ConstEvalErr { kind: NonConstPath, ..}) |
-                Err(ConstEvalErr { kind: UnresolvedPath, ..}) |
-                Err(ConstEvalErr { kind: ErroneousReferencedConstant(_), ..}) |
-                Err(ConstEvalErr { kind: Math(ConstMathErr::Overflow(Op::Shr)), ..}) |
-                Err(ConstEvalErr { kind: Math(ConstMathErr::Overflow(Op::Shl)), ..}) |
-                Err(ConstEvalErr { kind: IndexOpFeatureGated, ..}) => {},
+                Err(ConstEvalErr { kind: UnimplementedConstVal(_), .. }) |
+                Err(ConstEvalErr { kind: MiscCatchAll, .. }) |
+                Err(ConstEvalErr { kind: MiscBinaryOp, .. }) |
+                Err(ConstEvalErr { kind: NonConstPath, .. }) |
+                Err(ConstEvalErr { kind: UnresolvedPath, .. }) |
+                Err(ConstEvalErr { kind: ErroneousReferencedConstant(_), .. }) |
+                Err(ConstEvalErr { kind: Math(ConstMathErr::Overflow(Op::Shr)), .. }) |
+                Err(ConstEvalErr { kind: Math(ConstMathErr::Overflow(Op::Shl)), .. }) |
+                Err(ConstEvalErr { kind: IndexOpFeatureGated, .. }) => {}
                 Err(msg) => {
-                    self.tcx.sess.add_lint(CONST_ERR, ex.id,
+                    self.tcx.sess.add_lint(CONST_ERR,
+                                           ex.id,
                                            msg.span,
                                            msg.description().into_oneline().into_owned())
                 }
@@ -434,8 +436,7 @@ fn visit_expr(&mut self, ex: &hir::Expr) {
 /// every nested expression. If the expression is not part
 /// of a const/static item, it is qualified for promotion
 /// instead of producing errors.
-fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
-                        e: &hir::Expr, node_ty: Ty<'tcx>) {
+fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node_ty: Ty<'tcx>) {
     match node_ty.sty {
         ty::TyStruct(def, _) |
         ty::TyEnum(def, _) if def.has_dtor() => {
@@ -635,12 +636,9 @@ fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Exp
         Some(&ty::adjustment::AdjustUnsafeFnPointer) |
         Some(&ty::adjustment::AdjustMutToConstPointer) => {}
 
-        Some(&ty::adjustment::AdjustDerefRef(
-            ty::adjustment::AutoDerefRef { autoderefs, .. }
-        )) => {
-            if (0..autoderefs as u32).any(|autoderef| {
-                    v.tcx.is_overloaded_autoderef(e.id, autoderef)
-            }) {
+        Some(&ty::adjustment::AdjustDerefRef(ty::adjustment::AutoDerefRef { autoderefs, .. })) => {
+            if (0..autoderefs as u32)
+                .any(|autoderef| v.tcx.is_overloaded_autoderef(e.id, autoderef)) {
                 v.add_qualif(ConstQualif::NOT_CONST);
             }
         }
@@ -648,12 +646,13 @@ fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Exp
 }
 
 pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    tcx.visit_all_items_in_krate(DepNode::CheckConst, &mut CheckCrateVisitor {
-        tcx: tcx,
-        mode: Mode::Var,
-        qualif: ConstQualif::NOT_CONST,
-        rvalue_borrows: NodeMap()
-    });
+    tcx.visit_all_items_in_krate(DepNode::CheckConst,
+                                 &mut CheckCrateVisitor {
+                                     tcx: tcx,
+                                     mode: Mode::Var,
+                                     qualif: ConstQualif::NOT_CONST,
+                                     rvalue_borrows: NodeMap(),
+                                 });
     tcx.sess.abort_if_errors();
 }
 
@@ -675,7 +674,7 @@ fn consume(&mut self,
 
                 Categorization::Rvalue(..) |
                 Categorization::Upvar(..) |
-                Categorization::Local(..) => break
+                Categorization::Local(..) => break,
             }
         }
     }
@@ -685,8 +684,7 @@ fn borrow(&mut self,
               cmt: mc::cmt<'tcx>,
               _loan_region: ty::Region,
               bk: ty::BorrowKind,
-              loan_cause: euv::LoanCause)
-    {
+              loan_cause: euv::LoanCause) {
         // Kind of hacky, but we allow Unsafe coercions in constants.
         // These occur when we convert a &T or *T to a *U, as well as
         // when making a thin pointer (e.g., `*T`) into a fat pointer
@@ -695,7 +693,7 @@ fn borrow(&mut self,
             euv::LoanCause::AutoUnsafe => {
                 return;
             }
-            _ => { }
+            _ => {}
         }
 
         let mut cur = &cmt;
@@ -715,7 +713,8 @@ fn borrow(&mut self,
                         // type of the expression.  `&mut [1]` has exactly the
                         // same representation as &mut 1.
                         match cmt.ty.sty {
-                            ty::TyArray(_, _) | ty::TySlice(_) => break,
+                            ty::TyArray(_, _) |
+                            ty::TySlice(_) => break,
                             _ => {}
                         }
                     }
@@ -732,27 +731,20 @@ fn borrow(&mut self,
                 }
 
                 Categorization::Upvar(..) |
-                Categorization::Local(..) => break
+                Categorization::Local(..) => break,
             }
         }
     }
 
-    fn decl_without_init(&mut self,
-                         _id: ast::NodeId,
-                         _span: Span) {}
+    fn decl_without_init(&mut self, _id: ast::NodeId, _span: Span) {}
     fn mutate(&mut self,
               _assignment_id: ast::NodeId,
               _assignment_span: Span,
               _assignee_cmt: mc::cmt,
-              _mode: euv::MutateMode) {}
+              _mode: euv::MutateMode) {
+    }
 
-    fn matched_pat(&mut self,
-                   _: &hir::Pat,
-                   _: mc::cmt,
-                   _: euv::MatchMode) {}
+    fn matched_pat(&mut self, _: &hir::Pat, _: mc::cmt, _: euv::MatchMode) {}
 
-    fn consume_pat(&mut self,
-                   _consume_pat: &hir::Pat,
-                   _cmt: mc::cmt,
-                   _mode: euv::ConsumeMode) {}
+    fn consume_pat(&mut self, _consume_pat: &hir::Pat, _cmt: mc::cmt, _mode: euv::ConsumeMode) {}
 }
index a616b95ef7203ad312ba54a6a6af4c127d907aca..7049040678e39f706499e9a7cc920dfe89f797aa 100644 (file)
 ```
 "##,
 
+E0130: r##"
+You declared a pattern as an argument in a foreign function declaration.
+Erroneous code example:
+
+```compile_fail
+extern {
+    fn foo((a, b): (u32, u32)); // error: patterns aren't allowed in foreign
+                                //        function declarations
+}
+```
+
+Please replace the pattern argument with a regular one. Example:
+
+```
+struct SomeStruct {
+    a: u32,
+    b: u32,
+}
+
+extern {
+    fn foo(s: SomeStruct); // ok!
+}
+```
+
+Or:
+
+```
+extern {
+    fn foo(a: (u32, u32)); // ok!
+}
+```
+"##,
+
 E0161: r##"
 A value was moved. However, its size was not known at compile time, and only
 values of a known size can be moved.
@@ -88,11 +121,11 @@ fn main() {
 
 For example, neither of the following can be sensibly compiled:
 
-```compile_fail
+```compile_fail,E0265
 const X: u32 = X;
 ```
 
-```compile_fail
+```compile_fail,E0265
 const X: u32 = Y;
 const Y: u32 = X;
 ```
@@ -102,7 +135,7 @@ fn main() {
 This error indicates the use of a loop keyword (`break` or `continue`) inside a
 closure but outside of any loop. Erroneous code example:
 
-```compile_fail
+```compile_fail,E0267
 let w = || { break; }; // error: `break` inside of a closure
 ```
 
@@ -126,7 +159,7 @@ fn main() {
 of a loop. Without a loop to break out of or continue in, no sensible action can
 be taken. Erroneous code example:
 
-```compile_fail
+```compile_fail,E0268
 fn some_func() {
     break; // error: `break` outside of loop
 }
@@ -187,4 +220,5 @@ pub fn foo() {}
 
 register_diagnostics! {
     E0472, // asm! is unsupported on this target
+    E0561, // patterns aren't allowed in function pointer types
 }
index 650613f4844f526facb139225cc39d3a8a46e1e4..e59c4a6fc4186bfbb9664dcf7042a630ce574de9 100644 (file)
 #![feature(rustc_private)]
 
 extern crate core;
-#[macro_use] extern crate rustc;
+#[macro_use]
+extern crate rustc;
 extern crate rustc_const_eval;
 extern crate rustc_const_math;
 
-#[macro_use] extern crate log;
-#[macro_use] extern crate syntax;
+#[macro_use]
+extern crate log;
+#[macro_use]
+extern crate syntax;
 extern crate syntax_pos;
 extern crate rustc_errors as errors;
 
index dd0f16baaa395d524e6e91bf2abdcb3dbe5e0d65..4e251793f6917ae645fc6c14c7581aa26c3f658d 100644 (file)
 
 #[derive(Clone, Copy, PartialEq)]
 enum Context {
-    Normal, Loop, Closure
+    Normal,
+    Loop,
+    Closure,
 }
 
 #[derive(Copy, Clone)]
 struct CheckLoopVisitor<'a> {
     sess: &'a Session,
-    cx: Context
+    cx: Context,
 }
 
 pub fn check_crate(sess: &Session, map: &Map) {
     let _task = map.dep_graph.in_task(DepNode::CheckLoops);
     let krate = map.krate();
-    krate.visit_all_items(&mut CheckLoopVisitor { sess: sess, cx: Normal });
+    krate.visit_all_items(&mut CheckLoopVisitor {
+        sess: sess,
+        cx: Normal,
+    });
 }
 
 impl<'a, 'v> Visitor<'v> for CheckLoopVisitor<'a> {
@@ -53,14 +58,14 @@ fn visit_expr(&mut self, e: &hir::Expr) {
             }
             hir::ExprBreak(_) => self.require_loop("break", e.span),
             hir::ExprAgain(_) => self.require_loop("continue", e.span),
-            _ => intravisit::walk_expr(self, e)
+            _ => intravisit::walk_expr(self, e),
         }
     }
 }
 
 impl<'a> CheckLoopVisitor<'a> {
-    fn with_context<F>(&mut self, cx: Context, f: F) where
-        F: FnOnce(&mut CheckLoopVisitor<'a>),
+    fn with_context<F>(&mut self, cx: Context, f: F)
+        where F: FnOnce(&mut CheckLoopVisitor<'a>)
     {
         let old_cx = self.cx;
         self.cx = cx;
@@ -72,12 +77,10 @@ fn require_loop(&self, name: &str, span: Span) {
         match self.cx {
             Loop => {}
             Closure => {
-                span_err!(self.sess, span, E0267,
-                                   "`{}` inside of a closure", name);
+                span_err!(self.sess, span, E0267, "`{}` inside of a closure", name);
             }
             Normal => {
-                span_err!(self.sess, span, E0268,
-                                   "`{}` outside of loop", name);
+                span_err!(self.sess, span, E0268, "`{}` outside of loop", name);
             }
         }
     }
index 314513a974ecdb826b728523403a5056c635a062..af3065d64e8db08bc7fd8ee36cca33a93971fff3 100644 (file)
 use syntax::visit;
 
 pub fn check_crate(sess: &Session, krate: &ast::Crate) {
-    if sess.target.target.options.allow_asm { return; }
+    if sess.target.target.options.allow_asm {
+        return;
+    }
 
-    visit::walk_crate(&mut CheckNoAsm { sess: sess, }, krate);
+    visit::walk_crate(&mut CheckNoAsm { sess: sess }, krate);
 }
 
 #[derive(Copy, Clone)]
@@ -32,9 +34,13 @@ struct CheckNoAsm<'a> {
 impl<'a> Visitor for CheckNoAsm<'a> {
     fn visit_expr(&mut self, e: &ast::Expr) {
         match e.node {
-            ast::ExprKind::InlineAsm(_) => span_err!(self.sess, e.span, E0472,
-                                                     "asm! is unsupported on this target"),
-            _ => {},
+            ast::ExprKind::InlineAsm(_) => {
+                span_err!(self.sess,
+                          e.span,
+                          E0472,
+                          "asm! is unsupported on this target")
+            }
+            _ => {}
         }
         visit::walk_expr(self, e)
     }
index d0938ad09a0da1bced4e17ef57d5c1c1096c97fe..8b2943a33c006aaced7fd7cee377a241ff187467 100644 (file)
 
 use rustc::dep_graph::DepNode;
 use rustc::hir::map as ast_map;
-use rustc::session::{Session, CompileResult};
+use rustc::session::{CompileResult, Session};
 use rustc::hir::def::{Def, DefMap};
 use rustc::util::nodemap::NodeMap;
 
-use syntax::{ast};
+use syntax::ast;
 use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax_pos::Span;
 use rustc::hir::intravisit::{self, Visitor};
@@ -41,18 +41,17 @@ fn visit_item(&mut self, it: &'ast hir::Item) {
         match it.node {
             hir::ItemStatic(..) |
             hir::ItemConst(..) => {
-                let mut recursion_visitor =
-                    CheckItemRecursionVisitor::new(self, &it.span);
+                let mut recursion_visitor = CheckItemRecursionVisitor::new(self, &it.span);
                 recursion_visitor.visit_item(it);
-            },
+            }
             hir::ItemEnum(ref enum_def, ref generics) => {
                 // We could process the whole enum, but handling the variants
                 // with discriminant expressions one by one gives more specific,
                 // less redundant output.
                 for variant in &enum_def.variants {
                     if let Some(_) = variant.node.disr_expr {
-                        let mut recursion_visitor =
-                            CheckItemRecursionVisitor::new(self, &variant.span);
+                        let mut recursion_visitor = CheckItemRecursionVisitor::new(self,
+                                                                                   &variant.span);
                         recursion_visitor.populate_enum_discriminants(enum_def);
                         recursion_visitor.visit_variant(variant, generics, it.id);
                     }
@@ -67,8 +66,7 @@ fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) {
         match ti.node {
             hir::ConstTraitItem(_, ref default) => {
                 if let Some(_) = *default {
-                    let mut recursion_visitor =
-                        CheckItemRecursionVisitor::new(self, &ti.span);
+                    let mut recursion_visitor = CheckItemRecursionVisitor::new(self, &ti.span);
                     recursion_visitor.visit_trait_item(ti);
                 }
             }
@@ -80,8 +78,7 @@ fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) {
     fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) {
         match ii.node {
             hir::ImplItemKind::Const(..) => {
-                let mut recursion_visitor =
-                    CheckItemRecursionVisitor::new(self, &ii.span);
+                let mut recursion_visitor = CheckItemRecursionVisitor::new(self, &ii.span);
                 recursion_visitor.visit_impl_item(ii);
             }
             _ => {}
@@ -117,7 +114,8 @@ struct CheckItemRecursionVisitor<'a, 'ast: 'a> {
 }
 
 impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> {
-    fn new(v: &'a CheckCrateVisitor<'a, 'ast>, span: &'a Span)
+    fn new(v: &'a CheckCrateVisitor<'a, 'ast>,
+           span: &'a Span)
            -> CheckItemRecursionVisitor<'a, 'ast> {
         CheckItemRecursionVisitor {
             root_span: span,
@@ -129,7 +127,8 @@ fn new(v: &'a CheckCrateVisitor<'a, 'ast>, span: &'a Span)
         }
     }
     fn with_item_id_pushed<F>(&mut self, id: ast::NodeId, f: F)
-          where F: Fn(&mut Self) {
+        where F: Fn(&mut Self)
+    {
         if self.idstack.iter().any(|&x| x == id) {
             let any_static = self.idstack.iter().any(|&x| {
                 if let ast_map::NodeItem(item) = self.ast_map.get(x) {
@@ -146,7 +145,9 @@ fn with_item_id_pushed<F>(&mut self, id: ast::NodeId, f: F)
                 if !self.sess.features.borrow().static_recursion {
                     emit_feature_err(&self.sess.parse_sess.span_diagnostic,
                                      "static_recursion",
-                                     *self.root_span, GateIssue::Language, "recursive static");
+                                     *self.root_span,
+                                     GateIssue::Language,
+                                     "recursive static");
                 }
             } else {
                 span_err!(self.sess, *self.root_span, E0265, "recursive constant");
@@ -170,7 +171,9 @@ fn populate_enum_discriminants(&self, enum_definition: &'ast hir::EnumDef) {
         // has no variants.
         let mut discriminant_map = self.discriminant_map.borrow_mut();
         match enum_definition.variants.first() {
-            None => { return; }
+            None => {
+                return;
+            }
             Some(variant) if discriminant_map.contains_key(&variant.node.data.id()) => {
                 return;
             }
@@ -203,14 +206,19 @@ fn visit_item(&mut self, it: &'ast hir::Item) {
         self.with_item_id_pushed(it.id, |v| intravisit::walk_item(v, it));
     }
 
-    fn visit_enum_def(&mut self, enum_definition: &'ast hir::EnumDef,
-                      generics: &'ast hir::Generics, item_id: ast::NodeId, _: Span) {
+    fn visit_enum_def(&mut self,
+                      enum_definition: &'ast hir::EnumDef,
+                      generics: &'ast hir::Generics,
+                      item_id: ast::NodeId,
+                      _: Span) {
         self.populate_enum_discriminants(enum_definition);
         intravisit::walk_enum_def(self, enum_definition, generics, item_id);
     }
 
-    fn visit_variant(&mut self, variant: &'ast hir::Variant,
-                     _: &'ast hir::Generics, _: ast::NodeId) {
+    fn visit_variant(&mut self,
+                     variant: &'ast hir::Variant,
+                     _: &'ast hir::Generics,
+                     _: ast::NodeId) {
         let variant_id = variant.node.data.id();
         let maybe_expr;
         if let Some(get_expr) = self.discriminant_map.borrow().get(&variant_id) {
@@ -246,18 +254,14 @@ fn visit_expr(&mut self, e: &'ast hir::Expr) {
                     Some(Def::Const(def_id)) => {
                         if let Some(node_id) = self.ast_map.as_local_node_id(def_id) {
                             match self.ast_map.get(node_id) {
-                                ast_map::NodeItem(item) =>
-                                    self.visit_item(item),
-                                ast_map::NodeTraitItem(item) =>
-                                    self.visit_trait_item(item),
-                                ast_map::NodeImplItem(item) =>
-                                    self.visit_impl_item(item),
-                                ast_map::NodeForeignItem(_) => {},
+                                ast_map::NodeItem(item) => self.visit_item(item),
+                                ast_map::NodeTraitItem(item) => self.visit_trait_item(item),
+                                ast_map::NodeImplItem(item) => self.visit_impl_item(item),
+                                ast_map::NodeForeignItem(_) => {}
                                 _ => {
-                                    span_bug!(
-                                        e.span,
-                                        "expected item, found {}",
-                                        self.ast_map.node_to_string(node_id));
+                                    span_bug!(e.span,
+                                              "expected item, found {}",
+                                              self.ast_map.node_to_string(node_id));
                                 }
                             }
                         }
@@ -268,9 +272,9 @@ fn visit_expr(&mut self, e: &'ast hir::Expr) {
                     // might be (if any).
                     Some(Def::Variant(enum_id, variant_id)) => {
                         if let Some(enum_node_id) = self.ast_map.as_local_node_id(enum_id) {
-                            if let hir::ItemEnum(ref enum_def, ref generics) =
-                                self.ast_map.expect_item(enum_node_id).node
-                            {
+                            if let hir::ItemEnum(ref enum_def, ref generics) = self.ast_map
+                                .expect_item(enum_node_id)
+                                .node {
                                 self.populate_enum_discriminants(enum_def);
                                 let enum_id = self.ast_map.as_local_node_id(enum_id).unwrap();
                                 let variant_id = self.ast_map.as_local_node_id(variant_id).unwrap();
@@ -283,10 +287,10 @@ fn visit_expr(&mut self, e: &'ast hir::Expr) {
                             }
                         }
                     }
-                    _ => ()
+                    _ => (),
                 }
-            },
-            _ => ()
+            }
+            _ => (),
         }
         intravisit::walk_expr(self, e);
     }
index 5867e48c7ca27b64d5fbea039fffde6a34a6ec8f..116c1b7a6d06f811eb29829e316cfedfe093d1e6 100644 (file)
@@ -16,7 +16,7 @@
 use resolve_imports::ImportDirectiveSubclass::{self, GlobImport};
 use Module;
 use Namespace::{self, TypeNS, ValueNS};
-use {NameBinding, NameBindingKind};
+use {NameBinding, NameBindingKind, ToNameBinding};
 use ParentLink::{ModuleParentLink, BlockParentLink};
 use Resolver;
 use {resolve_error, resolve_struct_error, ResolutionError};
 
 use syntax_pos::{Span, DUMMY_SP};
 
-trait ToNameBinding<'a> {
-    fn to_name_binding(self) -> NameBinding<'a>;
-}
-
 impl<'a> ToNameBinding<'a> for (Module<'a>, Span, ty::Visibility) {
     fn to_name_binding(self) -> NameBinding<'a> {
         NameBinding { kind: NameBindingKind::Module(self.0), span: self.1, vis: self.2 }
@@ -68,18 +64,13 @@ pub fn build_reduced_graph(&mut self, krate: &Crate) {
         visit::walk_crate(&mut visitor, krate);
     }
 
-    /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined.
-    fn try_define<T>(&self, parent: Module<'b>, name: Name, ns: Namespace, def: T)
-        where T: ToNameBinding<'b>
-    {
-        let _ = parent.try_define_child(name, ns, def.to_name_binding());
-    }
-
     /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
     /// otherwise, reports an error.
-    fn define<T: ToNameBinding<'b>>(&self, parent: Module<'b>, name: Name, ns: Namespace, def: T) {
+    fn define<T>(&mut self, parent: Module<'b>, name: Name, ns: Namespace, def: T)
+        where T: ToNameBinding<'b>,
+    {
         let binding = def.to_name_binding();
-        if let Err(old_binding) = parent.try_define_child(name, ns, binding.clone()) {
+        if let Err(old_binding) = self.try_define(parent, name, ns, binding.clone()) {
             self.report_conflict(parent, name, ns, old_binding, &binding);
         }
     }
@@ -399,14 +390,14 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, xcd
                        name, vis);
                 let parent_link = ModuleParentLink(parent, name);
                 let module = self.new_module(parent_link, Some(def), true);
-                self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
+                let _ = self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
             }
             Def::Variant(_, variant_id) => {
                 debug!("(building reduced graph for external crate) building variant {}", name);
                 // Variants are always treated as importable to allow them to be glob used.
                 // All variants are defined in both type and value namespaces as future-proofing.
-                self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
-                self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
+                let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
+                let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
                 if self.session.cstore.variant_kind(variant_id) == Some(VariantKind::Struct) {
                     // Not adding fields for variants as they are not accessed with a self receiver
                     self.structs.insert(variant_id, Vec::new());
@@ -419,7 +410,7 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, xcd
             Def::Method(..) => {
                 debug!("(building reduced graph for external crate) building value (fn/static) {}",
                        name);
-                self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
+                let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
             }
             Def::Trait(def_id) => {
                 debug!("(building reduced graph for external crate) building type {}", name);
@@ -441,20 +432,20 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, xcd
 
                 let parent_link = ModuleParentLink(parent, name);
                 let module = self.new_module(parent_link, Some(def), true);
-                self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
+                let _ = self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
             }
             Def::TyAlias(..) | Def::AssociatedTy(..) => {
                 debug!("(building reduced graph for external crate) building type {}", name);
-                self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
+                let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
             }
             Def::Struct(def_id)
                 if self.session.cstore.tuple_struct_definition_if_ctor(def_id).is_none() => {
                 debug!("(building reduced graph for external crate) building type and value for {}",
                        name);
-                self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
+                let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
                 if let Some(ctor_def_id) = self.session.cstore.struct_ctor_def_id(def_id) {
                     let def = Def::Struct(ctor_def_id);
-                    self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
+                    let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
                 }
 
                 // Record the def ID and fields of this struct.
index 3e860150a35fdfbe3f2379e81cc727f3783f4778..11ef75ee6a8fc4fcc90596feebccca7687c16fb0 100644 (file)
@@ -146,6 +146,7 @@ pub trait MyTrait {
 }
 
 use foo::MyTrait::do_something;
+// error: `do_something` is not directly importable
 
 fn main() {}
 ```
@@ -153,6 +154,45 @@ fn main() {}
 It's invalid to directly import methods belonging to a trait or concrete type.
 "##,
 
+E0254: r##"
+Attempt was made to import an item whereas an extern crate with this name has
+already been imported.
+
+Erroneous code example:
+
+```compile_fail,E0254
+extern crate collections;
+
+mod foo {
+    pub trait collections {
+        fn do_something();
+    }
+}
+
+use foo::collections; // error: an extern crate named `collections` has already
+                      //        been imported in this module
+
+fn main() {}
+```
+
+To fix issue issue, you have to rename at least one of the two imports.
+Example:
+
+```ignore
+extern crate collections as libcollections; // ok!
+
+mod foo {
+    pub trait collections {
+        fn do_something();
+    }
+}
+
+use foo::collections;
+
+fn main() {}
+```
+"##,
+
 E0255: r##"
 You can't import a value whose name is the same as another value defined in the
 module.
@@ -1237,7 +1277,6 @@ impl Foo for i32 {}
 register_diagnostics! {
 //  E0153, unused error code
 //  E0157, unused error code
-    E0254, // import conflicts with imported crate in this module
 //  E0257,
 //  E0258,
     E0402, // cannot use an outer type parameter in this context
index 8c8cf1da467388cc98c3bec6d88c8cfda283e077..9f1f07004f4aecc9978fefb658e20a85a3b3fbbf 100644 (file)
@@ -158,7 +158,7 @@ enum ResolutionError<'a> {
     /// error E0435: attempt to use a non-constant value in a constant
     AttemptToUseNonConstantValueInConstant,
     /// error E0530: X bindings cannot shadow Ys
-    BindingShadowsSomethingUnacceptable(&'a str, &'a str, Name),
+    BindingShadowsSomethingUnacceptable(&'a str, Name, &'a NameBinding<'a>),
     /// error E0531: unresolved pattern path kind `name`
     PatPathUnresolved(&'a str, &'a Path),
     /// error E0532: expected pattern path kind, found another pattern path kind
@@ -219,7 +219,13 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
                              name)
         }
         ResolutionError::IsNotATrait(name) => {
-            struct_span_err!(resolver.session, span, E0404, "`{}` is not a trait", name)
+            let mut err = struct_span_err!(resolver.session,
+                                           span,
+                                           E0404,
+                                           "`{}` is not a trait",
+                                           name);
+            err.span_label(span, &format!("not a trait"));
+            err
         }
         ResolutionError::UndeclaredTraitName(name, candidates) => {
             let mut err = struct_span_err!(resolver.session,
@@ -422,17 +428,16 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
                              E0435,
                              "attempt to use a non-constant value in a constant")
         }
-        ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, shadows_what, name) => {
+        ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => {
+            let shadows_what = PathResolution::new(binding.def().unwrap()).kind_name();
             let mut err = struct_span_err!(resolver.session,
                                            span,
                                            E0530,
                                            "{}s cannot shadow {}s", what_binding, shadows_what);
             err.span_label(span, &format!("cannot be named the same as a {}", shadows_what));
-            if let Success(binding) = resolver.current_module.resolve_name(name, ValueNS, true) {
-                let participle = if binding.is_import() { "imported" } else { "defined" };
-                err.span_label(binding.span, &format!("a {} `{}` is {} here",
-                                                      shadows_what, name, participle));
-            }
+            let participle = if binding.is_import() { "imported" } else { "defined" };
+            let msg = &format!("a {} `{}` is {} here", shadows_what, name, participle);
+            err.span_label(binding.span, msg);
             err
         }
         ResolutionError::PatPathUnresolved(expected_what, path) => {
@@ -712,12 +717,16 @@ fn local_def(self) -> LocalDef {
         }
     }
 
-    fn module(self) -> Option<Module<'a>> {
+    fn item(self) -> Option<&'a NameBinding<'a>> {
         match self {
-            LexicalScopeBinding::Item(binding) => binding.module(),
+            LexicalScopeBinding::Item(binding) => Some(binding),
             _ => None,
         }
     }
+
+    fn module(self) -> Option<Module<'a>> {
+        self.item().and_then(NameBinding::module)
+    }
 }
 
 /// The link from a module up to its nearest parent node.
@@ -818,6 +827,16 @@ pub struct NameBinding<'a> {
     vis: ty::Visibility,
 }
 
+pub trait ToNameBinding<'a> {
+    fn to_name_binding(self) -> NameBinding<'a>;
+}
+
+impl<'a> ToNameBinding<'a> for NameBinding<'a> {
+    fn to_name_binding(self) -> NameBinding<'a> {
+        self
+    }
+}
+
 #[derive(Clone, Debug)]
 enum NameBindingKind<'a> {
     Def(Def),
@@ -1197,34 +1216,27 @@ fn get_ribs<'b>(&'b mut self, ns: Namespace) -> &'b mut Vec<Rib<'a>> {
         match ns { ValueNS => &mut self.value_ribs, TypeNS => &mut self.type_ribs }
     }
 
-    #[inline]
-    fn record_use(&mut self, name: Name, binding: &'a NameBinding<'a>) {
+    fn record_use(&mut self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>) {
         // track extern crates for unused_extern_crate lint
         if let Some(DefId { krate, .. }) = binding.module().and_then(ModuleS::def_id) {
             self.used_crates.insert(krate);
         }
 
-        let directive = match binding.kind {
-            NameBindingKind::Import { directive, .. } => directive,
-            _ => return,
-        };
-
-        if !self.make_glob_map {
-            return;
-        }
-        if self.glob_map.contains_key(&directive.id) {
-            self.glob_map.get_mut(&directive.id).unwrap().insert(name);
-            return;
+        if let NameBindingKind::Import { directive, .. } = binding.kind {
+            self.used_imports.insert((directive.id, ns));
+            self.add_to_glob_map(directive.id, name);
         }
+    }
 
-        let mut new_set = FnvHashSet();
-        new_set.insert(name);
-        self.glob_map.insert(directive.id, new_set);
+    fn add_to_glob_map(&mut self, id: NodeId, name: Name) {
+        if self.make_glob_map {
+            self.glob_map.entry(id).or_insert_with(FnvHashSet).insert(name);
+        }
     }
 
-    /// Resolves the given module path from the given root `module_`.
+    /// Resolves the given module path from the given root `search_module`.
     fn resolve_module_path_from_root(&mut self,
-                                     module_: Module<'a>,
+                                     mut search_module: Module<'a>,
                                      module_path: &[Name],
                                      index: usize,
                                      span: Span)
@@ -1241,7 +1253,6 @@ fn search_parent_externals(needle: Name, module: Module) -> Option<Module> {
             }
         }
 
-        let mut search_module = module_;
         let mut index = index;
         let module_path_len = module_path.len();
 
@@ -1438,10 +1449,9 @@ fn resolve_ident_in_lexical_scope(&mut self,
     }
 
     /// Returns the nearest normal module parent of the given module.
-    fn get_nearest_normal_module_parent(&self, module_: Module<'a>) -> Option<Module<'a>> {
-        let mut module_ = module_;
+    fn get_nearest_normal_module_parent(&self, mut module: Module<'a>) -> Option<Module<'a>> {
         loop {
-            match module_.parent_link {
+            match module.parent_link {
                 NoParentLink => return None,
                 ModuleParentLink(new_module, _) |
                 BlockParentLink(new_module, _) => {
@@ -1449,7 +1459,7 @@ fn get_nearest_normal_module_parent(&self, module_: Module<'a>) -> Option<Module
                     if new_module.is_normal() {
                         return Some(new_module);
                     }
-                    module_ = new_module;
+                    module = new_module;
                 }
             }
         }
@@ -1457,12 +1467,12 @@ fn get_nearest_normal_module_parent(&self, module_: Module<'a>) -> Option<Module
 
     /// Returns the nearest normal module parent of the given module, or the
     /// module itself if it is a normal module.
-    fn get_nearest_normal_module_parent_or_self(&self, module_: Module<'a>) -> Module<'a> {
-        if module_.is_normal() {
-            return module_;
+    fn get_nearest_normal_module_parent_or_self(&self, module: Module<'a>) -> Module<'a> {
+        if module.is_normal() {
+            return module;
         }
-        match self.get_nearest_normal_module_parent(module_) {
-            None => module_,
+        match self.get_nearest_normal_module_parent(module) {
+            None => module,
             Some(new_module) => new_module,
         }
     }
@@ -1479,8 +1489,8 @@ fn resolve_module_prefix(&mut self, module_path: &[Name], span: Span)
             "super" => 0,
             _ => return Success(NoPrefixFound),
         };
-        let module_ = self.current_module;
-        let mut containing_module = self.get_nearest_normal_module_parent_or_self(module_);
+        let mut containing_module =
+            self.get_nearest_normal_module_parent_or_self(self.current_module);
 
         // Now loop through all the `super`s we find.
         while i < module_path.len() && "super" == module_path[i].as_str() {
@@ -1519,10 +1529,7 @@ fn resolve_name_in_module(&mut self,
         self.populate_module_if_necessary(module);
         module.resolve_name(name, namespace, use_lexical_scope).and_then(|binding| {
             if record_used {
-                if let NameBindingKind::Import { directive, .. } = binding.kind {
-                    self.used_imports.insert((directive.id, namespace));
-                }
-                self.record_use(name, binding);
+                self.record_use(name, namespace, binding);
             }
             Success(binding)
         })
@@ -1807,39 +1814,25 @@ fn resolve_trait_reference(&mut self,
                                path_depth: usize)
                                -> Result<PathResolution, ()> {
         self.resolve_path(id, trait_path, path_depth, TypeNS).and_then(|path_res| {
-            if let Def::Trait(_) = path_res.base_def {
-                debug!("(resolving trait) found trait def: {:?}", path_res);
-                Ok(path_res)
-            } else {
-                let mut err =
-                    resolve_struct_error(self,
-                                  trait_path.span,
-                                  ResolutionError::IsNotATrait(&path_names_to_string(trait_path,
-                                                                                      path_depth)));
-
-                // If it's a typedef, give a note
-                if let Def::TyAlias(..) = path_res.base_def {
-                    let trait_name = trait_path.segments.last().unwrap().identifier.name;
-                    err.span_label(trait_path.span,
-                                   &format!("`{}` is not a trait", trait_name));
-
-                    let definition_site = {
-                        let segments = &trait_path.segments;
-                        if trait_path.global {
-                            self.resolve_crate_relative_path(trait_path.span, segments, TypeNS)
-                        } else {
-                            self.resolve_module_relative_path(trait_path.span, segments, TypeNS)
-                        }.map(|binding| binding.span).unwrap_or(syntax_pos::DUMMY_SP)
-                    };
-
-                    if definition_site != syntax_pos::DUMMY_SP {
-                        err.span_label(definition_site,
-                                       &format!("type aliases cannot be used for traits"));
-                    }
+            match path_res.base_def {
+                Def::Trait(_) => {
+                    debug!("(resolving trait) found trait def: {:?}", path_res);
+                    return Ok(path_res);
                 }
-                err.emit();
-                Err(true)
+                Def::Err => return Err(true),
+                _ => {}
+            }
+
+            let mut err = resolve_struct_error(self, trait_path.span, {
+                ResolutionError::IsNotATrait(&path_names_to_string(trait_path, path_depth))
+            });
+
+            // If it's a typedef, give a note
+            if let Def::TyAlias(..) = path_res.base_def {
+                err.note(&format!("type aliases cannot be used for traits"));
             }
+            err.emit();
+            Err(true)
         }).map_err(|error_reported| {
             if error_reported { return }
 
@@ -2316,16 +2309,17 @@ fn resolve_pattern(&mut self,
                 PatKind::Ident(bmode, ref ident, ref opt_pat) => {
                     // First try to resolve the identifier as some existing
                     // entity, then fall back to a fresh binding.
-                    let resolution = self.resolve_identifier(ident.node, ValueNS, true)
-                                         .map(|local_def| PathResolution::new(local_def.def))
-                                         .and_then(|resolution| {
+                    let binding = self.resolve_ident_in_lexical_scope(ident.node, ValueNS, false)
+                                      .and_then(LexicalScopeBinding::item);
+                    let resolution = binding.and_then(NameBinding::def).and_then(|def| {
                         let always_binding = !pat_src.is_refutable() || opt_pat.is_some() ||
                                              bmode != BindingMode::ByValue(Mutability::Immutable);
-                        match resolution.base_def {
+                        match def {
                             Def::Struct(..) | Def::Variant(..) |
                             Def::Const(..) | Def::AssociatedConst(..) if !always_binding => {
                                 // A constant, unit variant, etc pattern.
-                                Some(resolution)
+                                self.record_use(ident.node.name, ValueNS, binding.unwrap());
+                                Some(PathResolution::new(def))
                             }
                             Def::Struct(..) | Def::Variant(..) |
                             Def::Const(..) | Def::AssociatedConst(..) | Def::Static(..) => {
@@ -2334,7 +2328,7 @@ fn resolve_pattern(&mut self,
                                     self,
                                     ident.span,
                                     ResolutionError::BindingShadowsSomethingUnacceptable(
-                                        pat_src.descr(), resolution.kind_name(), ident.node.name)
+                                        pat_src.descr(), ident.node.name, binding.unwrap())
                                 );
                                 None
                             }
@@ -3144,10 +3138,10 @@ fn add_trait_info(found_traits: &mut Vec<TraitCandidate>,
                         if let NameBindingKind::Import { directive, .. } = binding.kind {
                             let id = directive.id;
                             this.maybe_unused_trait_imports.insert(id);
+                            this.add_to_glob_map(id, trait_name);
                             import_id = Some(id);
                         }
                         add_trait_info(&mut found_traits, trait_def_id, import_id, name);
-                        this.record_use(trait_name, binding);
                     }
                 }
             };
@@ -3381,7 +3375,11 @@ fn report_conflict(&self,
             (true, _) | (_, true) => struct_span_err!(self.session, span, E0260, "{}", msg),
             _ => match (old_binding.is_import(), binding.is_import()) {
                 (false, false) => struct_span_err!(self.session, span, E0428, "{}", msg),
-                (true, true) => struct_span_err!(self.session, span, E0252, "{}", msg),
+                (true, true) => {
+                    let mut e = struct_span_err!(self.session, span, E0252, "{}", msg);
+                    e.span_label(span, &format!("already imported"));
+                    e
+                },
                 _ => {
                     let mut e = struct_span_err!(self.session, span, E0255, "{}", msg);
                     e.span_label(span, &format!("`{}` was already imported", name));
index fc5e2a48e876ccc2eaf5391dd85a4e399f7ec2ee..6986f99926e1e43d9dd07874d5d25b29a9d4d6df 100644 (file)
@@ -12,7 +12,7 @@
 
 use Module;
 use Namespace::{self, TypeNS, ValueNS};
-use {NameBinding, NameBindingKind, PrivacyError};
+use {NameBinding, NameBindingKind, PrivacyError, ToNameBinding};
 use ResolveResult;
 use ResolveResult::*;
 use Resolver;
@@ -21,7 +21,7 @@
 use {resolve_error, ResolutionError};
 
 use rustc::ty;
-use rustc::lint;
+use rustc::lint::builtin::PRIVATE_IN_PUBLIC;
 use rustc::hir::def::*;
 
 use syntax::ast::{NodeId, Name};
@@ -71,19 +71,6 @@ pub struct ImportDirective<'a> {
 }
 
 impl<'a> ImportDirective<'a> {
-    // Given the binding to which this directive resolves in a particular namespace,
-    // this returns the binding for the name this directive defines in that namespace.
-    fn import(&'a self, binding: &'a NameBinding<'a>) -> NameBinding<'a> {
-        NameBinding {
-            kind: NameBindingKind::Import {
-                binding: binding,
-                directive: self,
-            },
-            span: self.span,
-            vis: self.vis,
-        }
-    }
-
     pub fn is_glob(&self) -> bool {
         match self.subclass { ImportDirectiveSubclass::GlobImport { .. } => true, _ => false }
     }
@@ -137,23 +124,6 @@ fn directive_failed(&mut self) {
 }
 
 impl<'a> NameResolution<'a> {
-    fn try_define(&mut self, binding: &'a NameBinding<'a>) -> Result<(), &'a NameBinding<'a>> {
-        if let Some(old_binding) = self.binding {
-            if binding.is_glob_import() {
-                self.duplicate_globs.push(binding);
-            } else if old_binding.is_glob_import() {
-                self.duplicate_globs.push(old_binding);
-                self.binding = Some(binding);
-            } else {
-                return Err(old_binding);
-            }
-        } else {
-            self.binding = Some(binding);
-        }
-
-        Ok(())
-    }
-
     // Returns the binding for the name if it is known or None if it not known.
     fn binding(&self) -> Option<&'a NameBinding<'a>> {
         self.binding.and_then(|binding| match self.single_imports {
@@ -203,24 +173,6 @@ fn try_result(&self, ns: Namespace, allow_private_imports: bool)
 
         self.binding.map(Success)
     }
-
-    fn report_conflicts<F: FnMut(&NameBinding, &NameBinding)>(&self, mut report: F) {
-        let binding = match self.binding {
-            Some(binding) => binding,
-            None => return,
-        };
-
-        for duplicate_glob in self.duplicate_globs.iter() {
-            // FIXME #31337: We currently allow items to shadow glob-imported re-exports.
-            if !binding.is_import() {
-                if let NameBindingKind::Import { binding, .. } = duplicate_glob.kind {
-                    if binding.is_import() { continue }
-                }
-            }
-
-            report(duplicate_glob, binding);
-        }
-    }
 }
 
 impl<'a> ::ModuleS<'a> {
@@ -261,14 +213,6 @@ pub fn resolve_name(&self, name: Name, ns: Namespace, allow_private_imports: boo
         Failed(None)
     }
 
-    // Define the name or return the existing binding if there is a collision.
-    pub fn try_define_child(&self, name: Name, ns: Namespace, binding: NameBinding<'a>)
-                            -> Result<(), &'a NameBinding<'a>> {
-        self.update_resolution(name, ns, |resolution| {
-            resolution.try_define(self.arenas.alloc_name_binding(binding))
-        })
-    }
-
     pub fn add_import_directive(&self,
                                 module_path: Vec<Name>,
                                 subclass: ImportDirectiveSubclass,
@@ -298,19 +242,59 @@ pub fn add_import_directive(&self,
             GlobImport { .. } => self.globs.borrow_mut().push(directive),
         }
     }
+}
+
+impl<'a> Resolver<'a> {
+    // Given a binding and an import directive that resolves to it,
+    // return the corresponding binding defined by the import directive.
+    fn import(&mut self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>)
+              -> NameBinding<'a> {
+        NameBinding {
+            kind: NameBindingKind::Import {
+                binding: binding,
+                directive: directive,
+            },
+            span: directive.span,
+            vis: directive.vis,
+        }
+    }
 
-    // Use `update` to mutate the resolution for the name.
+    // Define the name or return the existing binding if there is a collision.
+    pub fn try_define<T>(&mut self, module: Module<'a>, name: Name, ns: Namespace, binding: T)
+                         -> Result<(), &'a NameBinding<'a>>
+        where T: ToNameBinding<'a>
+    {
+        let binding = self.arenas.alloc_name_binding(binding.to_name_binding());
+        self.update_resolution(module, name, ns, |_, resolution| {
+            if let Some(old_binding) = resolution.binding {
+                if binding.is_glob_import() {
+                    resolution.duplicate_globs.push(binding);
+                } else if old_binding.is_glob_import() {
+                    resolution.duplicate_globs.push(old_binding);
+                    resolution.binding = Some(binding);
+                } else {
+                    return Err(old_binding);
+                }
+            } else {
+                resolution.binding = Some(binding);
+            }
+
+            Ok(())
+        })
+    }
+
+    // Use `f` to mutate the resolution of the name in the module.
     // If the resolution becomes a success, define it in the module's glob importers.
-    fn update_resolution<T, F>(&self, name: Name, ns: Namespace, update: F) -> T
-        where F: FnOnce(&mut NameResolution<'a>) -> T
+    fn update_resolution<T, F>(&mut self, module: Module<'a>, name: Name, ns: Namespace, f: F) -> T
+        where F: FnOnce(&mut Resolver<'a>, &mut NameResolution<'a>) -> T
     {
-        // Ensure that `resolution` isn't borrowed during `define_in_glob_importers`,
-        // where it might end up getting re-defined via a glob cycle.
+        // Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
+        // during which the resolution might end up getting re-defined via a glob cycle.
         let (new_binding, t) = {
-            let mut resolution = &mut *self.resolution(name, ns).borrow_mut();
+            let mut resolution = &mut *module.resolution(name, ns).borrow_mut();
             let was_known = resolution.binding().is_some();
 
-            let t = update(resolution);
+            let t = f(self, resolution);
 
             if was_known { return t; }
             match resolution.binding() {
@@ -319,15 +303,15 @@ fn update_resolution<T, F>(&self, name: Name, ns: Namespace, update: F) -> T
             }
         };
 
-        self.define_in_glob_importers(name, ns, new_binding);
-        t
-    }
-
-    fn define_in_glob_importers(&self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>) {
-        if !binding.is_importable() || !binding.is_pseudo_public() { return }
-        for &(importer, directive) in self.glob_importers.borrow_mut().iter() {
-            let _ = importer.try_define_child(name, ns, directive.import(binding));
+        // Define `new_binding` in `module`s glob importers.
+        if new_binding.is_importable() && new_binding.is_pseudo_public() {
+            for &(importer, directive) in module.glob_importers.borrow_mut().iter() {
+                let imported_binding = self.import(new_binding, directive);
+                let _ = self.try_define(importer, name, ns, imported_binding);
+            }
         }
+
+        t
     }
 }
 
@@ -343,6 +327,25 @@ struct ImportResolver<'a, 'b: 'a> {
     resolver: &'a mut Resolver<'b>,
 }
 
+impl<'a, 'b: 'a> ::std::ops::Deref for ImportResolver<'a, 'b> {
+    type Target = Resolver<'b>;
+    fn deref(&self) -> &Resolver<'b> {
+        self.resolver
+    }
+}
+
+impl<'a, 'b: 'a> ::std::ops::DerefMut for ImportResolver<'a, 'b> {
+    fn deref_mut(&mut self) -> &mut Resolver<'b> {
+        self.resolver
+    }
+}
+
+impl<'a, 'b: 'a> ty::NodeIdTree for ImportResolver<'a, 'b> {
+    fn is_descendant_of(&self, node: NodeId, ancestor: NodeId) -> bool {
+        self.resolver.is_descendant_of(node, ancestor)
+    }
+}
+
 impl<'a, 'b:'a> ImportResolver<'a, 'b> {
     // Import resolution
     //
@@ -360,31 +363,29 @@ fn resolve_imports(&mut self) {
         let mut errors = Vec::new();
 
         loop {
-            debug!("(resolving imports) iteration {}, {} imports left",
-                   i,
-                   self.resolver.unresolved_imports);
+            debug!("(resolving imports) iteration {}, {} imports left", i, self.unresolved_imports);
 
             // Attempt to resolve imports in all local modules.
-            for module in self.resolver.arenas.local_modules().iter() {
-                self.resolver.current_module = module;
+            for module in self.arenas.local_modules().iter() {
+                self.current_module = module;
                 self.resolve_imports_in_current_module(&mut errors);
             }
 
-            if self.resolver.unresolved_imports == 0 {
+            if self.unresolved_imports == 0 {
                 debug!("(resolving imports) success");
-                for module in self.resolver.arenas.local_modules().iter() {
+                for module in self.arenas.local_modules().iter() {
                     self.finalize_resolutions_in(module, false);
                 }
                 break;
             }
 
-            if self.resolver.unresolved_imports == prev_unresolved_imports {
+            if self.unresolved_imports == prev_unresolved_imports {
                 // resolving failed
                 // Report unresolved imports only if no hard error was already reported
                 // to avoid generating multiple errors on the same import.
                 // Imports that are still indeterminate at this point are actually blocked
                 // by errored imports, so there is no point reporting them.
-                for module in self.resolver.arenas.local_modules().iter() {
+                for module in self.arenas.local_modules().iter() {
                     self.finalize_resolutions_in(module, errors.len() == 0);
                 }
                 for e in errors {
@@ -394,29 +395,31 @@ fn resolve_imports(&mut self) {
             }
 
             i += 1;
-            prev_unresolved_imports = self.resolver.unresolved_imports;
+            prev_unresolved_imports = self.unresolved_imports;
         }
     }
 
     // Define a "dummy" resolution containing a Def::Err as a placeholder for a
     // failed resolution
-    fn import_dummy_binding(&self, source_module: Module<'b>, directive: &'b ImportDirective<'b>) {
+    fn import_dummy_binding(&mut self,
+                            source_module: Module<'b>,
+                            directive: &'b ImportDirective<'b>) {
         if let SingleImport { target, .. } = directive.subclass {
-            let dummy_binding = self.resolver.arenas.alloc_name_binding(NameBinding {
+            let dummy_binding = self.arenas.alloc_name_binding(NameBinding {
                 kind: NameBindingKind::Def(Def::Err),
                 span: DUMMY_SP,
                 vis: ty::Visibility::Public,
             });
-            let dummy_binding = directive.import(dummy_binding);
+            let dummy_binding = self.import(dummy_binding, directive);
 
-            let _ = source_module.try_define_child(target, ValueNS, dummy_binding.clone());
-            let _ = source_module.try_define_child(target, TypeNS, dummy_binding);
+            let _ = self.try_define(source_module, target, ValueNS, dummy_binding.clone());
+            let _ = self.try_define(source_module, target, TypeNS, dummy_binding);
         }
     }
 
     /// Resolves an `ImportResolvingError` into the correct enum discriminant
     /// and passes that on to `resolve_error`.
-    fn import_resolving_error(&self, e: ImportResolvingError<'b>) {
+    fn import_resolving_error(&mut self, e: ImportResolvingError<'b>) {
         // If the error is a single failed import then create a "fake" import
         // resolution for it so that later resolve stages won't complain.
         self.import_dummy_binding(e.source_module, e.import_directive);
@@ -430,7 +433,7 @@ fn import_resolving_error(&self, e: ImportResolvingError<'b>) {
     /// Attempts to resolve imports for the given module only.
     fn resolve_imports_in_current_module(&mut self, errors: &mut Vec<ImportResolvingError<'b>>) {
         let mut imports = Vec::new();
-        let mut unresolved_imports = self.resolver.current_module.unresolved_imports.borrow_mut();
+        let mut unresolved_imports = self.current_module.unresolved_imports.borrow_mut();
         ::std::mem::swap(&mut imports, &mut unresolved_imports);
 
         for import_directive in imports {
@@ -441,7 +444,7 @@ fn resolve_imports_in_current_module(&mut self, errors: &mut Vec<ImportResolving
                         None => (import_directive.span, String::new()),
                     };
                     errors.push(ImportResolvingError {
-                        source_module: self.resolver.current_module,
+                        source_module: self.current_module,
                         import_directive: import_directive,
                         span: span,
                         help: help,
@@ -450,8 +453,8 @@ fn resolve_imports_in_current_module(&mut self, errors: &mut Vec<ImportResolving
                 Indeterminate => unresolved_imports.push(import_directive),
                 Success(()) => {
                     // Decrement the count of unresolved imports.
-                    assert!(self.resolver.unresolved_imports >= 1);
-                    self.resolver.unresolved_imports -= 1;
+                    assert!(self.unresolved_imports >= 1);
+                    self.unresolved_imports -= 1;
                 }
             }
         }
@@ -465,13 +468,13 @@ fn resolve_imports_in_current_module(&mut self, errors: &mut Vec<ImportResolving
     fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResult<()> {
         debug!("(resolving import for module) resolving import `{}::...` in `{}`",
                names_to_string(&directive.module_path),
-               module_to_string(self.resolver.current_module));
+               module_to_string(self.current_module));
 
         let target_module = match directive.target_module.get() {
             Some(module) => module,
-            _ => match self.resolver.resolve_module_path(&directive.module_path,
-                                                         DontUseLexicalScope,
-                                                         directive.span) {
+            _ => match self.resolve_module_path(&directive.module_path,
+                                                DontUseLexicalScope,
+                                                directive.span) {
                 Success(module) => module,
                 Indeterminate => return Indeterminate,
                 Failed(err) => return Failed(err),
@@ -486,38 +489,36 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResul
         };
 
         // We need to resolve both namespaces for this to succeed.
-        let value_result =
-            self.resolver.resolve_name_in_module(target_module, source, ValueNS, false, true);
-        let type_result =
-            self.resolver.resolve_name_in_module(target_module, source, TypeNS, false, true);
+        let value_result = self.resolve_name_in_module(target_module, source, ValueNS, false, true);
+        let type_result = self.resolve_name_in_module(target_module, source, TypeNS, false, true);
 
-        let module_ = self.resolver.current_module;
+        let module = self.current_module;
         let mut privacy_error = true;
         for &(ns, result, determined) in &[(ValueNS, &value_result, value_determined),
                                            (TypeNS, &type_result, type_determined)] {
             match *result {
                 Failed(..) if !determined.get() => {
                     determined.set(true);
-                    module_.update_resolution(target, ns, |resolution| {
+                    self.update_resolution(module, target, ns, |_, resolution| {
                         resolution.single_imports.directive_failed()
                     });
                 }
                 Success(binding) if !binding.is_importable() => {
                     let msg = format!("`{}` is not directly importable", target);
-                    span_err!(self.resolver.session, directive.span, E0253, "{}", &msg);
+                    span_err!(self.session, directive.span, E0253, "{}", &msg);
                     // Do not import this illegal binding. Import a dummy binding and pretend
                     // everything is fine
-                    self.import_dummy_binding(module_, directive);
+                    self.import_dummy_binding(module, directive);
                     return Success(());
                 }
-                Success(binding) if !self.resolver.is_accessible(binding.vis) => {}
+                Success(binding) if !self.is_accessible(binding.vis) => {}
                 Success(binding) if !determined.get() => {
                     determined.set(true);
-                    let imported_binding = directive.import(binding);
-                    let conflict = module_.try_define_child(target, ns, imported_binding);
+                    let imported_binding = self.import(binding, directive);
+                    let conflict = self.try_define(module, target, ns, imported_binding);
                     if let Err(old_binding) = conflict {
-                        let binding = &directive.import(binding);
-                        self.resolver.report_conflict(module_, target, ns, binding, old_binding);
+                        let binding = &self.import(binding, directive);
+                        self.report_conflict(module, target, ns, binding, old_binding);
                     }
                     privacy_error = false;
                 }
@@ -556,39 +557,35 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResul
         if privacy_error {
             for &(ns, result) in &[(ValueNS, &value_result), (TypeNS, &type_result)] {
                 let binding = match *result { Success(binding) => binding, _ => continue };
-                self.resolver.privacy_errors.push(PrivacyError(directive.span, source, binding));
-                let _ = module_.try_define_child(target, ns, directive.import(binding));
+                self.privacy_errors.push(PrivacyError(directive.span, source, binding));
+                let imported_binding = self.import(binding, directive);
+                let _ = self.try_define(module, target, ns, imported_binding);
             }
         }
 
         match (&value_result, &type_result) {
-            (&Success(binding), _) if !binding.pseudo_vis()
-                                              .is_at_least(directive.vis, self.resolver) &&
-                                      self.resolver.is_accessible(binding.vis) => {
+            (&Success(binding), _) if !binding.pseudo_vis().is_at_least(directive.vis, self) &&
+                                      self.is_accessible(binding.vis) => {
                 let msg = format!("`{}` is private, and cannot be reexported", source);
                 let note_msg = format!("consider marking `{}` as `pub` in the imported module",
                                         source);
-                struct_span_err!(self.resolver.session, directive.span, E0364, "{}", &msg)
+                struct_span_err!(self.session, directive.span, E0364, "{}", &msg)
                     .span_note(directive.span, &note_msg)
                     .emit();
             }
 
-            (_, &Success(binding)) if !binding.pseudo_vis()
-                                              .is_at_least(directive.vis, self.resolver) &&
-                                      self.resolver.is_accessible(binding.vis) => {
+            (_, &Success(binding)) if !binding.pseudo_vis().is_at_least(directive.vis, self) &&
+                                      self.is_accessible(binding.vis) => {
                 if binding.is_extern_crate() {
                     let msg = format!("extern crate `{}` is private, and cannot be reexported \
                                        (error E0364), consider declaring with `pub`",
                                        source);
-                    self.resolver.session.add_lint(lint::builtin::PRIVATE_IN_PUBLIC,
-                                                   directive.id,
-                                                   directive.span,
-                                                   msg);
+                    self.session.add_lint(PRIVATE_IN_PUBLIC, directive.id, directive.span, msg);
                 } else {
                     let msg = format!("`{}` is private, and cannot be reexported", source);
                     let note_msg =
                         format!("consider declaring type or module `{}` with `pub`", source);
-                    struct_span_err!(self.resolver.session, directive.span, E0365, "{}", &msg)
+                    struct_span_err!(self.session, directive.span, E0365, "{}", &msg)
                         .span_note(directive.span, &note_msg)
                         .emit();
                 }
@@ -605,7 +602,7 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResul
             None => value_result.success().and_then(NameBinding::def).unwrap(),
         };
         let path_resolution = PathResolution::new(def);
-        self.resolver.def_map.insert(directive.id, path_resolution);
+        self.def_map.insert(directive.id, path_resolution);
 
         debug!("(resolving single import) successfully resolved import");
         return Success(());
@@ -618,40 +615,41 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResul
     fn resolve_glob_import(&mut self, target_module: Module<'b>, directive: &'b ImportDirective<'b>)
                            -> ResolveResult<()> {
         if let Some(Def::Trait(_)) = target_module.def {
-            self.resolver.session.span_err(directive.span, "items in traits are not importable.");
+            self.session.span_err(directive.span, "items in traits are not importable.");
         }
 
-        let module_ = self.resolver.current_module;
-        if module_.def_id() == target_module.def_id() {
+        let module = self.current_module;
+        if module.def_id() == target_module.def_id() {
             // This means we are trying to glob import a module into itself, and it is a no-go
             let msg = "Cannot glob-import a module into itself.".into();
             return Failed(Some((directive.span, msg)));
         }
-        self.resolver.populate_module_if_necessary(target_module);
+        self.populate_module_if_necessary(target_module);
 
         if let GlobImport { is_prelude: true } = directive.subclass {
-            self.resolver.prelude = Some(target_module);
+            self.prelude = Some(target_module);
             return Success(());
         }
 
         // Add to target_module's glob_importers
-        target_module.glob_importers.borrow_mut().push((module_, directive));
+        target_module.glob_importers.borrow_mut().push((module, directive));
 
-        // Ensure that `resolutions` isn't borrowed during `try_define_child`,
+        // Ensure that `resolutions` isn't borrowed during `try_define`,
         // since it might get updated via a glob cycle.
         let bindings = target_module.resolutions.borrow().iter().filter_map(|(name, resolution)| {
             resolution.borrow().binding().map(|binding| (*name, binding))
         }).collect::<Vec<_>>();
         for ((name, ns), binding) in bindings {
             if binding.is_importable() && binding.is_pseudo_public() {
-                let _ = module_.try_define_child(name, ns, directive.import(binding));
+                let imported_binding = self.import(binding, directive);
+                let _ = self.try_define(module, name, ns, imported_binding);
             }
         }
 
         // Record the destination of this import
         if let Some(did) = target_module.def_id() {
             let resolution = PathResolution::new(Def::Mod(did));
-            self.resolver.def_map.insert(directive.id, resolution);
+            self.def_map.insert(directive.id, resolution);
         }
 
         debug!("(resolving glob import) successfully resolved import");
@@ -667,15 +665,23 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>, report_unresolved_impo
         let mut reexports = Vec::new();
         for (&(name, ns), resolution) in module.resolutions.borrow().iter() {
             let resolution = resolution.borrow();
-            resolution.report_conflicts(|b1, b2| {
-                self.resolver.report_conflict(module, name, ns, b1, b2)
-            });
-
             let binding = match resolution.binding {
                 Some(binding) => binding,
                 None => continue,
             };
 
+            // Report conflicts
+            for duplicate_glob in resolution.duplicate_globs.iter() {
+                // FIXME #31337: We currently allow items to shadow glob-imported re-exports.
+                if !binding.is_import() {
+                    if let NameBindingKind::Import { binding, .. } = duplicate_glob.kind {
+                        if binding.is_import() { continue }
+                    }
+                }
+
+                self.report_conflict(module, name, ns, duplicate_glob, binding);
+            }
+
             if binding.vis == ty::Visibility::Public &&
                (binding.is_import() || binding.is_extern_crate()) {
                 if let Some(def) = binding.def() {
@@ -685,20 +691,19 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>, report_unresolved_impo
 
             if let NameBindingKind::Import { binding: orig_binding, directive, .. } = binding.kind {
                 if ns == TypeNS && orig_binding.is_variant() &&
-                   !orig_binding.vis.is_at_least(binding.vis, self.resolver) {
+                   !orig_binding.vis.is_at_least(binding.vis, self) {
                     let msg = format!("variant `{}` is private, and cannot be reexported \
                                        (error E0364), consider declaring its enum as `pub`",
                                       name);
-                    let lint = lint::builtin::PRIVATE_IN_PUBLIC;
-                    self.resolver.session.add_lint(lint, directive.id, binding.span, msg);
+                    self.session.add_lint(PRIVATE_IN_PUBLIC, directive.id, binding.span, msg);
                 }
             }
         }
 
         if reexports.len() > 0 {
             if let Some(def_id) = module.def_id() {
-                let node_id = self.resolver.definitions.as_local_node_id(def_id).unwrap();
-                self.resolver.export_map.insert(node_id, reexports);
+                let node_id = self.definitions.as_local_node_id(def_id).unwrap();
+                self.export_map.insert(node_id, reexports);
             }
         }
 
index 6c2a09f8060c5a4b36fb87e1701d74bff6f62ed7..587c03af3abb6d6eaae9fbdd1c73a2650912049e 100644 (file)
@@ -552,13 +552,13 @@ pub fn llvm_type(&self, ccx: &CrateContext) -> Type {
     pub fn apply_attrs_llfn(&self, llfn: ValueRef) {
         let mut i = if self.ret.is_indirect() { 1 } else { 0 };
         if !self.ret.is_ignore() {
-            self.ret.attrs.apply_llfn(i, llfn);
+            self.ret.attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn);
         }
         i += 1;
         for arg in &self.args {
             if !arg.is_ignore() {
                 if arg.pad.is_some() { i += 1; }
-                arg.attrs.apply_llfn(i, llfn);
+                arg.attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn);
                 i += 1;
             }
         }
@@ -567,13 +567,13 @@ pub fn apply_attrs_llfn(&self, llfn: ValueRef) {
     pub fn apply_attrs_callsite(&self, callsite: ValueRef) {
         let mut i = if self.ret.is_indirect() { 1 } else { 0 };
         if !self.ret.is_ignore() {
-            self.ret.attrs.apply_callsite(i, callsite);
+            self.ret.attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite);
         }
         i += 1;
         for arg in &self.args {
             if !arg.is_ignore() {
                 if arg.pad.is_some() { i += 1; }
-                arg.attrs.apply_callsite(i, callsite);
+                arg.attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite);
                 i += 1;
             }
         }
index e27bec683757a9b19f95c33354aac160f7829802..5514fb0f4efc37b067b21439af683cf9d6a8f754 100644 (file)
@@ -83,8 +83,8 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     };
 
     let dialect = match ia.dialect {
-        AsmDialect::Att   => llvm::AD_ATT,
-        AsmDialect::Intel => llvm::AD_Intel
+        AsmDialect::Att   => llvm::AsmDialect::Att,
+        AsmDialect::Intel => llvm::AsmDialect::Intel,
     };
 
     let asm = CString::new(ia.asm.as_bytes()).unwrap();
index 01e9970dc76c349d5b499a85056f9a3d4c4d9d72..62eac35e0abd9766d64b7b471c6cf2022e15e182 100644 (file)
@@ -9,8 +9,8 @@
 // except according to those terms.
 //! Set and unset common attributes on LLVM values.
 
-use libc::c_uint;
-use llvm::{self, ValueRef};
+use llvm::{self, Attribute, ValueRef};
+use llvm::AttributePlace::Function;
 pub use syntax::attr::InlineAttr;
 use syntax::ast;
 use context::CrateContext;
 pub fn inline(val: ValueRef, inline: InlineAttr) {
     use self::InlineAttr::*;
     match inline {
-        Hint   => llvm::SetFunctionAttribute(val, llvm::Attribute::InlineHint),
-        Always => llvm::SetFunctionAttribute(val, llvm::Attribute::AlwaysInline),
-        Never  => llvm::SetFunctionAttribute(val, llvm::Attribute::NoInline),
+        Hint   => Attribute::InlineHint.apply_llfn(Function, val),
+        Always => Attribute::AlwaysInline.apply_llfn(Function, val),
+        Never  => Attribute::NoInline.apply_llfn(Function, val),
         None   => {
-            let attr = llvm::Attribute::InlineHint |
-                       llvm::Attribute::AlwaysInline |
-                       llvm::Attribute::NoInline;
-            llvm::RemoveFunctionAttributes(val, attr)
+            let attr = Attribute::InlineHint |
+                       Attribute::AlwaysInline |
+                       Attribute::NoInline;
+            attr.unapply_llfn(Function, val)
         },
     };
 }
@@ -35,56 +35,37 @@ pub fn inline(val: ValueRef, inline: InlineAttr) {
 /// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function.
 #[inline]
 pub fn emit_uwtable(val: ValueRef, emit: bool) {
-    if emit {
-        llvm::SetFunctionAttribute(val, llvm::Attribute::UWTable);
-    } else {
-        llvm::RemoveFunctionAttributes(val, llvm::Attribute::UWTable);
-    }
+    Attribute::UWTable.toggle_llfn(Function, val, emit);
 }
 
 /// Tell LLVM whether the function can or cannot unwind.
 #[inline]
 pub fn unwind(val: ValueRef, can_unwind: bool) {
-    if can_unwind {
-        llvm::RemoveFunctionAttributes(val, llvm::Attribute::NoUnwind);
-    } else {
-        llvm::SetFunctionAttribute(val, llvm::Attribute::NoUnwind);
-    }
+    Attribute::NoUnwind.toggle_llfn(Function, val, !can_unwind);
 }
 
 /// Tell LLVM whether it should optimise function for size.
 #[inline]
 #[allow(dead_code)] // possibly useful function
 pub fn set_optimize_for_size(val: ValueRef, optimize: bool) {
-    if optimize {
-        llvm::SetFunctionAttribute(val, llvm::Attribute::OptimizeForSize);
-    } else {
-        llvm::RemoveFunctionAttributes(val, llvm::Attribute::OptimizeForSize);
-    }
+    Attribute::OptimizeForSize.toggle_llfn(Function, val, optimize);
 }
 
 /// Tell LLVM if this function should be 'naked', i.e. skip the epilogue and prologue.
 #[inline]
 pub fn naked(val: ValueRef, is_naked: bool) {
-    if is_naked {
-        llvm::SetFunctionAttribute(val, llvm::Attribute::Naked);
-    } else {
-        llvm::RemoveFunctionAttributes(val, llvm::Attribute::Naked);
-    }
+    Attribute::Naked.toggle_llfn(Function, val, is_naked);
 }
 
 pub fn set_frame_pointer_elimination(ccx: &CrateContext, llfn: ValueRef) {
     // FIXME: #11906: Omitting frame pointers breaks retrieving the value of a
     // parameter.
     if ccx.sess().must_not_eliminate_frame_pointers() {
-        unsafe {
-            let attr = "no-frame-pointer-elim\0".as_ptr() as *const _;
-            let val = "true\0".as_ptr() as *const _;
-            llvm::LLVMAddFunctionAttrStringValue(llfn,
-                                                 llvm::FunctionIndex as c_uint,
-                                                 attr,
-                                                 val);
-        }
+        llvm::AddFunctionAttrStringValue(
+            llfn,
+            llvm::AttributePlace::Function,
+            "no-frame-pointer-elim\0",
+            "true\0")
     }
 }
 
@@ -98,13 +79,12 @@ pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRe
 
     for attr in attrs {
         if attr.check_name("cold") {
-            llvm::Attributes::default().set(llvm::Attribute::Cold)
-                .apply_llfn(llvm::FunctionIndex as usize, llfn)
+            Attribute::Cold.apply_llfn(Function, llfn);
         } else if attr.check_name("naked") {
             naked(llfn, true);
         } else if attr.check_name("allocator") {
-            llvm::Attributes::default().set(llvm::Attribute::NoAlias)
-                .apply_llfn(llvm::ReturnIndex as usize, llfn)
+            Attribute::NoAlias.apply_llfn(
+                llvm::AttributePlace::ReturnValue(), llfn);
         } else if attr.check_name("unwind") {
             unwind(llfn, true);
         }
index 29019f3683dead592681278afbbce89fcf349461..e063209799f16b0ba4641cf4fdcb524b6473f431 100644 (file)
@@ -293,7 +293,7 @@ fn build_with_llvm(&mut self, kind: ArchiveKind) -> io::Result<()> {
                                                members.as_ptr(),
                                                self.should_update_symbols,
                                                kind);
-            let ret = if r != 0 {
+            let ret = if r.into_result().is_err() {
                 let err = llvm::LLVMRustGetLastError();
                 let msg = if err.is_null() {
                     "failed to write archive".to_string()
index 4890b3c6683f0054c2eb93b89bf068860ecfe5f8..7025de523c378c4a68097bf17b08d64002fcdb12 100644 (file)
@@ -54,7 +54,7 @@ pub fn write_output_file(
         let output_c = path2cstr(output);
         let result = llvm::LLVMRustWriteOutputFile(
                 target, pm, m, output_c.as_ptr(), file_type);
-        if !result {
+        if result.into_result().is_err() {
             llvm_err(handler, format!("could not write output to {}", output.display()));
         }
     }
@@ -138,11 +138,11 @@ fn target_feature(sess: &Session) -> String {
 
 fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel {
     match optimize {
-      config::OptLevel::No => llvm::CodeGenLevelNone,
-      config::OptLevel::Less => llvm::CodeGenLevelLess,
-      config::OptLevel::Default => llvm::CodeGenLevelDefault,
-      config::OptLevel::Aggressive => llvm::CodeGenLevelAggressive,
-      _ => llvm::CodeGenLevelDefault,
+      config::OptLevel::No => llvm::CodeGenOptLevel::None,
+      config::OptLevel::Less => llvm::CodeGenOptLevel::Less,
+      config::OptLevel::Default => llvm::CodeGenOptLevel::Default,
+      config::OptLevel::Aggressive => llvm::CodeGenOptLevel::Aggressive,
+      _ => llvm::CodeGenOptLevel::Default,
     }
 }
 
@@ -169,11 +169,11 @@ pub fn create_target_machine(sess: &Session) -> TargetMachineRef {
     };
 
     let code_model = match code_model_arg {
-        "default" => llvm::CodeModelDefault,
-        "small" => llvm::CodeModelSmall,
-        "kernel" => llvm::CodeModelKernel,
-        "medium" => llvm::CodeModelMedium,
-        "large" => llvm::CodeModelLarge,
+        "default" => llvm::CodeModel::Default,
+        "small" => llvm::CodeModel::Small,
+        "kernel" => llvm::CodeModel::Kernel,
+        "medium" => llvm::CodeModel::Medium,
+        "large" => llvm::CodeModel::Large,
         _ => {
             sess.err(&format!("{:?} is not a valid code model",
                              sess.opts
@@ -365,7 +365,7 @@ struct HandlerFreeVars<'a> {
                                         cookie: c_uint) {
     let HandlerFreeVars { cgcx, .. } = *(user as *const HandlerFreeVars);
 
-    let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s))
+    let msg = llvm::build_string(|s| llvm::LLVMRustWriteSMDiagnosticToString(diag, s))
         .expect("non-UTF8 SMDiagnostic");
 
     report_inline_asm(cgcx, &msg[..], cookie);
@@ -421,7 +421,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
     };
     let fv = &fv as *const HandlerFreeVars as *mut c_void;
 
-    llvm::LLVMSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, fv);
+    llvm::LLVMRustSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, fv);
     llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, fv);
 
     let module_name = Some(&mtrans.name[..]);
@@ -449,9 +449,9 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
                 return false;
             }
             let pass_manager = match llvm::LLVMRustPassKind(pass) {
-                llvm::SupportedPassKind::Function => fpm,
-                llvm::SupportedPassKind::Module => mpm,
-                llvm::SupportedPassKind::Unsupported => {
+                llvm::PassKind::Function => fpm,
+                llvm::PassKind::Module => mpm,
+                llvm::PassKind::Other => {
                     cgcx.handler.err("Encountered LLVM pass kind we can't handle");
                     return true
                 },
@@ -579,7 +579,7 @@ unsafe fn with_codegen<F>(tm: TargetMachineRef,
             };
             with_codegen(tm, llmod, config.no_builtins, |cpm| {
                 write_output_file(cgcx.handler, tm, cpm, llmod, &path,
-                                  llvm::AssemblyFileType);
+                                  llvm::FileType::AssemblyFile);
             });
             if config.emit_obj {
                 llvm::LLVMDisposeModule(llmod);
@@ -588,7 +588,8 @@ unsafe fn with_codegen<F>(tm: TargetMachineRef,
 
         if write_obj {
             with_codegen(tm, llmod, config.no_builtins, |cpm| {
-                write_output_file(cgcx.handler, tm, cpm, llmod, &obj_out, llvm::ObjectFileType);
+                write_output_file(cgcx.handler, tm, cpm, llmod, &obj_out,
+                                  llvm::FileType::ObjectFile);
             });
         }
     });
@@ -1093,7 +1094,7 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
     // reasonable defaults and prepare it to actually populate the pass
     // manager.
     let builder = llvm::LLVMPassManagerBuilderCreate();
-    let opt_level = config.opt_level.unwrap_or(llvm::CodeGenLevelNone);
+    let opt_level = config.opt_level.unwrap_or(llvm::CodeGenOptLevel::None);
     let opt_size = config.opt_size.unwrap_or(llvm::CodeGenOptSizeNone);
     let inline_threshold = config.inline_threshold;
 
@@ -1117,7 +1118,7 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
         (_, _, Some(t)) => {
             llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, t as u32);
         }
-        (llvm::CodeGenLevelAggressive, _, _) => {
+        (llvm::CodeGenOptLevel::Aggressive, _, _) => {
             llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 275);
         }
         (_, llvm::CodeGenOptSizeDefault, _) => {
@@ -1126,15 +1127,18 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
         (_, llvm::CodeGenOptSizeAggressive, _) => {
             llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 25);
         }
-        (llvm::CodeGenLevelNone, _, _) => {
+        (llvm::CodeGenOptLevel::None, _, _) => {
             llvm::LLVMRustAddAlwaysInlinePass(builder, false);
         }
-        (llvm::CodeGenLevelLess, _, _) => {
+        (llvm::CodeGenOptLevel::Less, _, _) => {
             llvm::LLVMRustAddAlwaysInlinePass(builder, true);
         }
-        (llvm::CodeGenLevelDefault, _, _) => {
+        (llvm::CodeGenOptLevel::Default, _, _) => {
             llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 225);
         }
+        (llvm::CodeGenOptLevel::Other, _, _) => {
+            bug!("CodeGenOptLevel::Other selected")
+        }
     }
 
     f(builder);
index 5a19ddff7462af5130a5b909334e19a34f2d22da..1077cb296c1ac307e2e5a07535ed1eaf11166825 100644 (file)
@@ -1918,9 +1918,9 @@ pub fn trans_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 }
 
 pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance<'tcx>) {
-    let instance = inline::maybe_inline_instance(ccx, instance);
+    let local_instance = inline::maybe_inline_instance(ccx, instance);
 
-    let fn_node_id = ccx.tcx().map.as_local_node_id(instance.def).unwrap();
+    let fn_node_id = ccx.tcx().map.as_local_node_id(local_instance.def).unwrap();
 
     let _s = StatRecorder::new(ccx, ccx.tcx().node_path_str(fn_node_id));
     debug!("trans_instance(instance={:?})", instance);
@@ -1936,7 +1936,7 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance
     let sig = ccx.tcx().normalize_associated_type(&sig);
     let abi = fn_ty.fn_abi();
 
-    let lldecl = match ccx.instances().borrow().get(&instance) {
+    let lldecl = match ccx.instances().borrow().get(&local_instance) {
         Some(&val) => val,
         None => bug!("Instance `{:?}` not already declared", instance)
     };
@@ -2347,8 +2347,9 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
                     let has_fixed_linkage = linkage_fixed_explicitly.contains(&name_cow);
 
                     if !is_referenced_somewhere && !is_reachable && !has_fixed_linkage {
-                        llvm::SetLinkage(val, llvm::InternalLinkage);
-                        llvm::SetDLLStorageClass(val, llvm::DefaultStorageClass);
+                        llvm::LLVMSetLinkage(val, llvm::InternalLinkage);
+                        llvm::LLVMSetDLLStorageClass(val,
+                                                     llvm::DLLStorageClass::Default);
                         llvm::UnsetComdat(val);
                     }
                 }
@@ -2393,7 +2394,7 @@ fn create_imps(cx: &CrateContextList) {
                                               imp_name.as_ptr() as *const _);
                 let init = llvm::LLVMConstBitCast(val, i8p_ty.to_ref());
                 llvm::LLVMSetInitializer(imp, init);
-                llvm::SetLinkage(imp, llvm::ExternalLinkage);
+                llvm::LLVMSetLinkage(imp, llvm::ExternalLinkage);
             }
         }
     }
index 4a7a5736b13a6fd4c49ccd1bc0e1e7d8fb085d27..8cd47bd148d0cf597e5241a65bc6b0b511a7635f 100644 (file)
@@ -12,7 +12,7 @@
 #![allow(non_snake_case)]
 
 use llvm;
-use llvm::{AtomicBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
+use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
 use llvm::{Opcode, IntPredicate, RealPredicate};
 use llvm::{ValueRef, BasicBlockRef};
 use common::*;
@@ -1117,7 +1117,7 @@ pub fn AtomicCmpXchg(cx: Block, dst: ValueRef,
                      weak: llvm::Bool) -> ValueRef {
     B(cx).atomic_cmpxchg(dst, cmp, src, order, failure_order, weak)
 }
-pub fn AtomicRMW(cx: Block, op: AtomicBinOp,
+pub fn AtomicRMW(cx: Block, op: AtomicRmwBinOp,
                  dst: ValueRef, src: ValueRef,
                  order: AtomicOrdering) -> ValueRef {
     B(cx).atomic_rmw(op, dst, src, order)
index 7495f2b753b86e711186ccc5ee919c985bb2fcb1..90f96af5496915527d9a71c0271dc2b61b64056b 100644 (file)
@@ -11,7 +11,7 @@
 #![allow(dead_code)] // FFI wrappers
 
 use llvm;
-use llvm::{AtomicBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
+use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
 use llvm::{Opcode, IntPredicate, RealPredicate, False, OperandBundleDef};
 use llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef};
 use base;
@@ -503,8 +503,8 @@ pub fn atomic_load(&self, ptr: ValueRef, order: AtomicOrdering) -> ValueRef {
         unsafe {
             let ty = Type::from_ref(llvm::LLVMTypeOf(ptr));
             let align = llalign_of_pref(self.ccx, ty.element_type());
-            llvm::LLVMBuildAtomicLoad(self.llbuilder, ptr, noname(), order,
-                                      align as c_uint)
+            llvm::LLVMRustBuildAtomicLoad(self.llbuilder, ptr, noname(), order,
+                                          align as c_uint)
         }
     }
 
@@ -565,7 +565,7 @@ pub fn atomic_store(&self, val: ValueRef, ptr: ValueRef, order: AtomicOrdering)
         unsafe {
             let ty = Type::from_ref(llvm::LLVMTypeOf(ptr));
             let align = llalign_of_pref(self.ccx, ty.element_type());
-            llvm::LLVMBuildAtomicStore(self.llbuilder, val, ptr, order, align as c_uint);
+            llvm::LLVMRustBuildAtomicStore(self.llbuilder, val, ptr, order, align as c_uint);
         }
     }
 
@@ -840,8 +840,8 @@ pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char,
         debug!("Asm Output Type: {:?}", output);
         let fty = Type::func(&argtys[..], &output);
         unsafe {
-            let v = llvm::LLVMInlineAsm(
-                fty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint);
+            let v = llvm::LLVMRustInlineAsm(
+                fty.to_ref(), asm, cons, volatile, alignstack, dia);
             self.call(v, inputs, None)
         }
     }
@@ -1087,7 +1087,7 @@ pub fn atomic_cmpxchg(&self, dst: ValueRef,
                                          order, failure_order, weak)
         }
     }
-    pub fn atomic_rmw(&self, op: AtomicBinOp,
+    pub fn atomic_rmw(&self, op: AtomicRmwBinOp,
                      dst: ValueRef, src: ValueRef,
                      order: AtomicOrdering) -> ValueRef {
         unsafe {
@@ -1097,7 +1097,7 @@ pub fn atomic_rmw(&self, op: AtomicBinOp,
 
     pub fn atomic_fence(&self, order: AtomicOrdering, scope: SynchronizationScope) {
         unsafe {
-            llvm::LLVMBuildAtomicFence(self.llbuilder, order, scope);
+            llvm::LLVMRustBuildAtomicFence(self.llbuilder, order, scope);
         }
     }
 }
index 6b9de4a48786d4eddbff71ee5f3120b71d3ecac8..e53a5edfc668519f2f305e8f63687419c7ebb83a 100644 (file)
@@ -249,11 +249,13 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
     if  !ccx.instances().borrow().contains_key(&instance) {
         let llfn = get_or_create_closure_declaration(ccx, closure_def_id, closure_substs);
 
-        if ccx.sess().target.target.options.allows_weak_linkage {
-            llvm::SetLinkage(llfn, llvm::WeakODRLinkage);
-            llvm::SetUniqueComdat(ccx.llmod(), llfn);
-        } else {
-            llvm::SetLinkage(llfn, llvm::InternalLinkage);
+        unsafe {
+            if ccx.sess().target.target.options.allows_weak_linkage {
+                llvm::LLVMSetLinkage(llfn, llvm::WeakODRLinkage);
+                llvm::SetUniqueComdat(ccx.llmod(), llfn);
+            } else {
+                llvm::LLVMSetLinkage(llfn, llvm::InternalLinkage);
+            }
         }
 
         // set an inline hint for all closures
index 6a1fc6bcffbfcde5bcc939e9282d185de7977c3f..b3729cc23f60fd3582253c9dbec04d102637ce67 100644 (file)
@@ -980,7 +980,7 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va
         });
         llvm::LLVMSetInitializer(g, sc);
         llvm::LLVMSetGlobalConstant(g, True);
-        llvm::SetLinkage(g, llvm::InternalLinkage);
+        llvm::LLVMSetLinkage(g, llvm::InternalLinkage);
 
         cx.const_cstr_cache().borrow_mut().insert(s, g);
         g
index 84c3b41fd0acb6855c19d98dbb640c5c92e274a0..769dd008af8f495c3602737f04e7b99e2187f7ed 100644 (file)
@@ -10,7 +10,7 @@
 
 
 use llvm;
-use llvm::{ConstFCmp, ConstICmp, SetLinkage, SetUnnamedAddr};
+use llvm::{SetUnnamedAddr};
 use llvm::{InternalLinkage, ValueRef, Bool, True};
 use middle::const_qualif::ConstQualif;
 use rustc_const_eval::{ConstEvalErr, lookup_const_fn_by_id, lookup_const_by_id, ErrKind};
@@ -125,7 +125,7 @@ pub fn addr_of_mut(ccx: &CrateContext,
         });
         llvm::LLVMSetInitializer(gv, cv);
         llvm::LLVMSetAlignment(gv, align);
-        SetLinkage(gv, InternalLinkage);
+        llvm::LLVMSetLinkage(gv, InternalLinkage);
         SetUnnamedAddr(gv, true);
         gv
     }
@@ -637,10 +637,10 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 hir::BiEq | hir::BiNe | hir::BiLt | hir::BiLe | hir::BiGt | hir::BiGe => {
                     if is_float {
                         let cmp = base::bin_op_to_fcmp_predicate(b.node);
-                        ConstFCmp(cmp, te1, te2)
+                        llvm::LLVMConstFCmp(cmp, te1, te2)
                     } else {
                         let cmp = base::bin_op_to_icmp_predicate(b.node, signed);
-                        ConstICmp(cmp, te1, te2)
+                        llvm::LLVMConstICmp(cmp, te1, te2)
                     }
                 },
             } } // unsafe { match b.node {
@@ -1072,7 +1072,7 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
                     unsafe {
                         // Declare a symbol `foo` with the desired linkage.
                         let g1 = declare::declare_global(ccx, &sym, llty2);
-                        llvm::SetLinkage(g1, linkage);
+                        llvm::LLVMSetLinkage(g1, linkage);
 
                         // Declare an internal global `extern_with_linkage_foo` which
                         // is initialized with the address of `foo`.  If `foo` is
@@ -1086,7 +1086,7 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
                             ccx.sess().span_fatal(span,
                                 &format!("symbol `{}` is already defined", &sym))
                         });
-                        llvm::SetLinkage(g2, llvm::InternalLinkage);
+                        llvm::LLVMSetLinkage(g2, llvm::InternalLinkage);
                         llvm::LLVMSetInitializer(g2, g1);
                         g2
                     }
@@ -1126,7 +1126,9 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
             }
         }
         if ccx.use_dll_storage_attrs() {
-            llvm::SetDLLStorageClass(g, llvm::DLLImportStorageClass);
+            unsafe {
+                llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
+            }
         }
         g
     };
@@ -1182,7 +1184,7 @@ pub fn trans_static(ccx: &CrateContext,
             let name_str_ref = CStr::from_ptr(llvm::LLVMGetValueName(datum.val));
             let name_string = CString::new(name_str_ref.to_bytes()).unwrap();
             llvm::LLVMSetValueName(datum.val, empty_string.as_ptr());
-            let new_g = llvm::LLVMGetOrInsertGlobal(
+            let new_g = llvm::LLVMRustGetOrInsertGlobal(
                 ccx.llmod(), name_string.as_ptr(), val_llty.to_ref());
             // To avoid breaking any invariants, we leave around the old
             // global for the moment; we'll replace all references to it
index 909b3d065075351fd68b446ba16131d2f551850f..97b03312d7963a5c27330ddc075213ee4d6fe312 100644 (file)
@@ -338,10 +338,10 @@ pub fn get_reloc_model(sess: &Session) -> llvm::RelocMode {
     };
 
     match reloc_model_arg {
-        "pic" => llvm::RelocPIC,
-        "static" => llvm::RelocStatic,
-        "default" => llvm::RelocDefault,
-        "dynamic-no-pic" => llvm::RelocDynamicNoPic,
+        "pic" => llvm::RelocMode::PIC,
+        "static" => llvm::RelocMode::Static,
+        "default" => llvm::RelocMode::Default,
+        "dynamic-no-pic" => llvm::RelocMode::DynamicNoPic,
         _ => {
             sess.err(&format!("{:?} is not a valid relocation mode",
                              sess.opts
@@ -360,7 +360,7 @@ fn is_any_library(sess: &Session) -> bool {
 }
 
 pub fn is_pie_binary(sess: &Session) -> bool {
-    !is_any_library(sess) && get_reloc_model(sess) == llvm::RelocPIC
+    !is_any_library(sess) && get_reloc_model(sess) == llvm::RelocMode::PIC
 }
 
 unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) {
index 0b75402486812b4706706c1363a284cdd2341ffd..fe6a48d4c559dac732df51158504bdb562f3f466 100644 (file)
@@ -133,7 +133,7 @@ fn make_mir_scope(ccx: &CrateContext,
     let loc = span_start(ccx, scope_data.span);
     scopes[scope] = unsafe {
     let file_metadata = file_metadata(ccx, &loc.file.name, &loc.file.abs_path);
-        llvm::LLVMDIBuilderCreateLexicalBlock(
+        llvm::LLVMRustDIBuilderCreateLexicalBlock(
             DIB(ccx),
             parent_scope,
             file_metadata,
@@ -156,7 +156,7 @@ fn with_new_scope<F>(cx: &CrateContext,
     let parent_scope = scope_stack.last().unwrap().scope_metadata;
 
     let scope_metadata = unsafe {
-        llvm::LLVMDIBuilderCreateLexicalBlock(
+        llvm::LLVMRustDIBuilderCreateLexicalBlock(
             DIB(cx),
             parent_scope,
             file_metadata,
@@ -272,7 +272,7 @@ fn walk_pattern(cx: &CrateContext,
                 let parent_scope = scope_stack.last().unwrap().scope_metadata;
 
                 let scope_metadata = unsafe {
-                    llvm::LLVMDIBuilderCreateLexicalBlock(
+                    llvm::LLVMRustDIBuilderCreateLexicalBlock(
                         DIB(cx),
                         parent_scope,
                         file_metadata,
index cf312855d75bc8bf081d13cbcf2e985d902244fc..0a8d490dcd2dd3e54601a69484f44d1eddf7aaea 100644 (file)
@@ -77,7 +77,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(ccx: &CrateContext)
             llvm::LLVMSetInitializer(section_var, C_bytes(ccx, section_contents));
             llvm::LLVMSetGlobalConstant(section_var, llvm::True);
             llvm::LLVMSetUnnamedAddr(section_var, llvm::True);
-            llvm::SetLinkage(section_var, llvm::Linkage::LinkOnceODRLinkage);
+            llvm::LLVMSetLinkage(section_var, llvm::Linkage::LinkOnceODRLinkage);
             // This should make sure that the whole section is not larger than
             // the string it contains. Otherwise we get a warning from GDB.
             llvm::LLVMSetAlignment(section_var, 1);
index e8051212552d81deaf5687a7303043d4f9aff440..ee13af80b2ba0aeff7741bb4a5a687305b0bbb50 100644 (file)
@@ -504,12 +504,12 @@ fn fixed_vec_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     };
 
     let subrange = unsafe {
-        llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)
+        llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)
     };
 
     let subscripts = create_DIArray(DIB(cx), &[subrange]);
     let metadata = unsafe {
-        llvm::LLVMDIBuilderCreateArrayType(
+        llvm::LLVMRustDIBuilderCreateArrayType(
             DIB(cx),
             bytes_to_bits(array_size_in_bytes),
             bytes_to_bits(element_type_align),
@@ -612,7 +612,7 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     return MetadataCreationResult::new(
         unsafe {
-            llvm::LLVMDIBuilderCreateSubroutineType(
+            llvm::LLVMRustDIBuilderCreateSubroutineType(
                 DIB(cx),
                 unknown_file_metadata(cx),
                 create_DIArray(DIB(cx), &signature_metadata[..]))
@@ -885,8 +885,8 @@ fn file_metadata_(cx: &CrateContext, key: &str, file_name: &str, work_dir: &str)
     let file_name = CString::new(file_name).unwrap();
     let work_dir = CString::new(work_dir).unwrap();
     let file_metadata = unsafe {
-        llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name.as_ptr(),
-                                      work_dir.as_ptr())
+        llvm::LLVMRustDIBuilderCreateFile(DIB(cx), file_name.as_ptr(),
+                                          work_dir.as_ptr())
     };
 
     let mut created_files = debug_context(cx).created_files.borrow_mut();
@@ -916,7 +916,7 @@ pub fn scope_metadata(fcx: &FunctionContext,
 
 pub fn diverging_type_metadata(cx: &CrateContext) -> DIType {
     unsafe {
-        llvm::LLVMDIBuilderCreateBasicType(
+        llvm::LLVMRustDIBuilderCreateBasicType(
             DIB(cx),
             "!\0".as_ptr() as *const _,
             bytes_to_bits(0),
@@ -951,7 +951,7 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let (size, align) = size_and_align_of(cx, llvm_type);
     let name = CString::new(name).unwrap();
     let ty_metadata = unsafe {
-        llvm::LLVMDIBuilderCreateBasicType(
+        llvm::LLVMRustDIBuilderCreateBasicType(
             DIB(cx),
             name.as_ptr(),
             bytes_to_bits(size),
@@ -971,7 +971,7 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let name = compute_debuginfo_type_name(cx, pointer_type, false);
     let name = CString::new(name).unwrap();
     let ptr_metadata = unsafe {
-        llvm::LLVMDIBuilderCreatePointerType(
+        llvm::LLVMRustDIBuilderCreatePointerType(
             DIB(cx),
             pointee_type_metadata,
             bytes_to_bits(pointer_size),
@@ -1017,7 +1017,7 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext,
     let flags = "\0";
     let split_name = "\0";
     return unsafe {
-        llvm::LLVMDIBuilderCreateCompileUnit(
+        llvm::LLVMRustDIBuilderCreateCompileUnit(
             debug_context.builder,
             DW_LANG_RUST,
             compile_unit_name,
@@ -1596,7 +1596,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let token = v.name.as_str();
             let name = CString::new(token.as_bytes()).unwrap();
             unsafe {
-                llvm::LLVMDIBuilderCreateEnumerator(
+                llvm::LLVMRustDIBuilderCreateEnumerator(
                     DIB(cx),
                     name.as_ptr(),
                     v.disr_val.to_u64_unchecked())
@@ -1623,7 +1623,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
                 let name = CString::new(discriminant_name.as_bytes()).unwrap();
                 let discriminant_type_metadata = unsafe {
-                    llvm::LLVMDIBuilderCreateEnumerationType(
+                    llvm::LLVMRustDIBuilderCreateEnumerationType(
                         DIB(cx),
                         containing_scope,
                         name.as_ptr(),
@@ -1667,7 +1667,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let enum_name = CString::new(enum_name).unwrap();
     let unique_type_id_str = CString::new(unique_type_id_str.as_bytes()).unwrap();
     let enum_metadata = unsafe {
-        llvm::LLVMDIBuilderCreateUnionType(
+        llvm::LLVMRustDIBuilderCreateUnionType(
         DIB(cx),
         containing_scope,
         enum_name.as_ptr(),
@@ -1769,7 +1769,7 @@ fn set_members_of_composite_type(cx: &CrateContext,
             let member_name = member_description.name.as_bytes();
             let member_name = CString::new(member_name).unwrap();
             unsafe {
-                llvm::LLVMDIBuilderCreateMemberType(
+                llvm::LLVMRustDIBuilderCreateMemberType(
                     DIB(cx),
                     composite_type_metadata,
                     member_name.as_ptr(),
@@ -1786,13 +1786,14 @@ fn set_members_of_composite_type(cx: &CrateContext,
 
     unsafe {
         let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
-        llvm::LLVMDICompositeTypeSetTypeArray(DIB(cx), composite_type_metadata, type_array);
+        llvm::LLVMRustDICompositeTypeSetTypeArray(
+            DIB(cx), composite_type_metadata, type_array);
     }
 }
 
-// A convenience wrapper around LLVMDIBuilderCreateStructType(). Does not do any
-// caching, does not add any fields to the struct. This can be done later with
-// set_members_of_composite_type().
+// A convenience wrapper around LLVMRustDIBuilderCreateStructType(). Does not do
+// any caching, does not add any fields to the struct. This can be done later
+// with set_members_of_composite_type().
 fn create_struct_stub(cx: &CrateContext,
                       struct_llvm_type: Type,
                       struct_type_name: &str,
@@ -1807,12 +1808,12 @@ fn create_struct_stub(cx: &CrateContext,
     let name = CString::new(struct_type_name).unwrap();
     let unique_type_id = CString::new(unique_type_id_str.as_bytes()).unwrap();
     let metadata_stub = unsafe {
-        // LLVMDIBuilderCreateStructType() wants an empty array. A null
+        // LLVMRustDIBuilderCreateStructType() wants an empty array. A null
         // pointer will lead to hard to trace and debug LLVM assertions
         // later on in llvm/lib/IR/Value.cpp.
         let empty_array = create_DIArray(DIB(cx), &[]);
 
-        llvm::LLVMDIBuilderCreateStructType(
+        llvm::LLVMRustDIBuilderCreateStructType(
             DIB(cx),
             containing_scope,
             name.as_ptr(),
@@ -1868,16 +1869,16 @@ pub fn create_global_var_metadata(cx: &CrateContext,
     let var_name = CString::new(var_name).unwrap();
     let linkage_name = CString::new(linkage_name).unwrap();
     unsafe {
-        llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
-                                                var_scope,
-                                                var_name.as_ptr(),
-                                                linkage_name.as_ptr(),
-                                                file_metadata,
-                                                line_number,
-                                                type_metadata,
-                                                is_local_to_unit,
-                                                global,
-                                                ptr::null_mut());
+        llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
+                                                    var_scope,
+                                                    var_name.as_ptr(),
+                                                    linkage_name.as_ptr(),
+                                                    file_metadata,
+                                                    line_number,
+                                                    type_metadata,
+                                                    is_local_to_unit,
+                                                    global,
+                                                    ptr::null_mut());
     }
 }
 
@@ -1980,10 +1981,10 @@ pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                                               env_index);
 
     let address_operations = unsafe {
-        [llvm::LLVMDIBuilderCreateOpDeref(),
-         llvm::LLVMDIBuilderCreateOpPlus(),
+        [llvm::LLVMRustDIBuilderCreateOpDeref(),
+         llvm::LLVMRustDIBuilderCreateOpPlus(),
          byte_offset_of_var_in_env as i64,
-         llvm::LLVMDIBuilderCreateOpDeref()]
+         llvm::LLVMRustDIBuilderCreateOpDeref()]
     };
 
     let address_op_count = if captured_by_ref {
@@ -2021,7 +2022,7 @@ pub fn create_match_binding_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     let scope_metadata = scope_metadata(bcx.fcx, binding.id, binding.span);
     let aops = unsafe {
-        [llvm::LLVMDIBuilderCreateOpDeref()]
+        [llvm::LLVMRustDIBuilderCreateOpDeref()]
     };
     // Regardless of the actual type (`T`) we're always passed the stack slot
     // (alloca) for the binding. For ByRef bindings that's a `T*` but for ByMove
index 0cb52c8768b04e06addcdc19985843e2d1865042..f2c7068565ee90d482bfb7471f6f5b0e7f879cbf 100644 (file)
@@ -18,7 +18,7 @@
 use self::namespace::mangled_name_of_item;
 use self::type_names::compute_debuginfo_type_name;
 use self::metadata::{type_metadata, diverging_type_metadata};
-use self::metadata::{file_metadata, scope_metadata, TypeMap};
+use self::metadata::{file_metadata, TypeMap};
 use self::source_loc::InternalDebugLocation::{self, UnknownLocation};
 
 use llvm;
@@ -32,6 +32,7 @@
 
 use abi::Abi;
 use common::{NodeIdAndSpan, CrateContext, FunctionContext, Block, BlockAndBuilder};
+use inline;
 use monomorphize::{self, Instance};
 use rustc::ty::{self, Ty};
 use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
@@ -88,7 +89,7 @@ pub struct CrateDebugContext<'tcx> {
 impl<'tcx> CrateDebugContext<'tcx> {
     pub fn new(llmod: ModuleRef) -> CrateDebugContext<'tcx> {
         debug!("CrateDebugContext::new");
-        let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) };
+        let builder = unsafe { llvm::LLVMRustDIBuilderCreate(llmod) };
         // DIBuilder inherits context from the module, so we'd better use the same one
         let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) };
         return CrateDebugContext {
@@ -178,8 +179,8 @@ pub fn finalize(cx: &CrateContext) {
     }
 
     unsafe {
-        llvm::LLVMDIBuilderFinalize(DIB(cx));
-        llvm::LLVMDIBuilderDispose(DIB(cx));
+        llvm::LLVMRustDIBuilderFinalize(DIB(cx));
+        llvm::LLVMRustDIBuilderDispose(DIB(cx));
         // Debuginfo generation in LLVM by default uses a higher
         // version of dwarf than OS X currently understands. We can
         // instruct LLVM to emit an older version of dwarf, however,
@@ -238,6 +239,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     // Do this here already, in case we do an early exit from this function.
     source_loc::set_debug_location(cx, None, UnknownLocation);
 
+    let instance = inline::maybe_inline_instance(cx, instance);
     let (containing_scope, span) = get_containing_scope_and_span(cx, instance);
 
     // This can be the case for functions inlined from another crate
@@ -250,7 +252,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     let function_type_metadata = unsafe {
         let fn_signature = get_function_signature(cx, sig, abi);
-        llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature)
+        llvm::LLVMRustDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature)
     };
 
     // Find the enclosing function, in case this is a closure.
@@ -284,7 +286,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let linkage_name = CString::new(linkage_name).unwrap();
 
     let fn_metadata = unsafe {
-        llvm::LLVMDIBuilderCreateFunction(
+        llvm::LLVMRustDIBuilderCreateFunction(
             DIB(cx),
             containing_scope,
             function_name.as_ptr(),
@@ -388,7 +390,7 @@ fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 let actual_type_metadata = type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
                 let name = CString::new(param.name.as_str().as_bytes()).unwrap();
                 unsafe {
-                    llvm::LLVMDIBuilderCreateTemplateTypeParameter(
+                    llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
                         DIB(cx),
                         ptr::null_mut(),
                         name.as_ptr(),
@@ -492,7 +494,7 @@ pub fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         (DirectVariable { alloca }, address_operations) |
         (IndirectVariable {alloca, address_operations}, _) => {
             let metadata = unsafe {
-                llvm::LLVMDIBuilderCreateVariable(
+                llvm::LLVMRustDIBuilderCreateVariable(
                     DIB(cx),
                     dwarf_tag,
                     scope_metadata,
@@ -510,7 +512,7 @@ pub fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 InternalDebugLocation::new(scope_metadata, loc.line, loc.col.to_usize()));
             unsafe {
                 let debug_loc = llvm::LLVMGetCurrentDebugLocation(cx.raw_builder());
-                let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
+                let instr = llvm::LLVMRustDIBuilderInsertDeclareAtEnd(
                     DIB(cx),
                     alloca,
                     metadata,
index 736a8c1c7d70c3561a541435cb09920a063837e9..5953ec4aaedfa3cb492de9d8a61f9fa4cf05beac 100644 (file)
@@ -78,7 +78,7 @@ pub fn item_namespace(ccx: &CrateContext, def_id: DefId) -> DIScope {
     };
 
     let scope = unsafe {
-        llvm::LLVMDIBuilderCreateNameSpace(
+        llvm::LLVMRustDIBuilderCreateNameSpace(
             DIB(ccx),
             parent_scope,
             namespace_name.as_ptr(),
index 9726001b4d42b71828a51298eee9127a817eff9d..d288b9dcef70bb379c2c89a6fecbd99da6d485f1 100644 (file)
@@ -206,7 +206,7 @@ pub fn set_debug_location(cx: &CrateContext,
             debug!("setting debug location to {} {}", line, col);
 
             unsafe {
-                llvm::LLVMDIBuilderCreateDebugLocation(
+                llvm::LLVMRustDIBuilderCreateDebugLocation(
                     debug_context(cx).llcontext,
                     line as c_uint,
                     col as c_uint,
index facdfe73ddc8e577c046cdccbfddc8d25b6f45cb..5734a12394113fe86a2c825652c0aa11540f1a9c 100644 (file)
@@ -40,7 +40,7 @@ pub fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool
 #[allow(non_snake_case)]
 pub fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray {
     return unsafe {
-        llvm::LLVMDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32)
+        llvm::LLVMRustDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32)
     };
 }
 
index 2746d3fb6b0b6788e76397504e968b60d460491f..324e8697ecae695ab61e3a6e550cdf085fa85fd2 100644 (file)
@@ -20,6 +20,7 @@
 //! * Use define_* family of methods when you might be defining the ValueRef.
 //! * When in doubt, define.
 use llvm::{self, ValueRef};
+use llvm::AttributePlace::Function;
 use rustc::ty;
 use abi::{Abi, FnType};
 use attributes;
@@ -40,7 +41,7 @@ pub fn declare_global(ccx: &CrateContext, name: &str, ty: Type) -> llvm::ValueRe
         bug!("name {:?} contains an interior null byte", name)
     });
     unsafe {
-        llvm::LLVMGetOrInsertGlobal(ccx.llmod(), namebuf.as_ptr(), ty.to_ref())
+        llvm::LLVMRustGetOrInsertGlobal(ccx.llmod(), namebuf.as_ptr(), ty.to_ref())
     }
 }
 
@@ -55,7 +56,7 @@ fn declare_raw_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty:
         bug!("name {:?} contains an interior null byte", name)
     });
     let llfn = unsafe {
-        llvm::LLVMGetOrInsertFunction(ccx.llmod(), namebuf.as_ptr(), ty.to_ref())
+        llvm::LLVMRustGetOrInsertFunction(ccx.llmod(), namebuf.as_ptr(), ty.to_ref())
     };
 
     llvm::SetFunctionCallConv(llfn, callconv);
@@ -65,16 +66,16 @@ fn declare_raw_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty:
 
     if ccx.tcx().sess.opts.cg.no_redzone
         .unwrap_or(ccx.tcx().sess.target.target.options.disable_redzone) {
-        llvm::SetFunctionAttribute(llfn, llvm::Attribute::NoRedZone)
+        llvm::Attribute::NoRedZone.apply_llfn(Function, llfn);
     }
 
     match ccx.tcx().sess.opts.cg.opt_level.as_ref().map(String::as_ref) {
         Some("s") => {
-            llvm::SetFunctionAttribute(llfn, llvm::Attribute::OptimizeForSize);
+            llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn);
         },
         Some("z") => {
-            llvm::SetFunctionAttribute(llfn, llvm::Attribute::MinSize);
-            llvm::SetFunctionAttribute(llfn, llvm::Attribute::OptimizeForSize);
+            llvm::Attribute::MinSize.apply_llfn(Function, llfn);
+            llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn);
         },
         _ => {},
     }
@@ -111,7 +112,7 @@ pub fn declare_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str,
     let llfn = declare_raw_fn(ccx, name, fty.cconv, fty.llvm_type(ccx));
 
     if sig.output == ty::FnDiverging {
-        llvm::SetFunctionAttribute(llfn, llvm::Attribute::NoReturn);
+        llvm::Attribute::NoReturn.apply_llfn(Function, llfn);
     }
 
     if abi != Abi::Rust && abi != Abi::RustCall {
@@ -162,7 +163,7 @@ pub fn define_internal_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                     name: &str,
                                     fn_type: ty::Ty<'tcx>) -> ValueRef {
     let llfn = define_fn(ccx, name, fn_type);
-    llvm::SetLinkage(llfn, llvm::InternalLinkage);
+    unsafe { llvm::LLVMSetLinkage(llfn, llvm::InternalLinkage) };
     llfn
 }
 
@@ -173,7 +174,7 @@ pub fn get_declared_value(ccx: &CrateContext, name: &str) -> Option<ValueRef> {
     let namebuf = CString::new(name).unwrap_or_else(|_|{
         bug!("name {:?} contains an interior null byte", name)
     });
-    let val = unsafe { llvm::LLVMGetNamedValue(ccx.llmod(), namebuf.as_ptr()) };
+    let val = unsafe { llvm::LLVMRustGetNamedValue(ccx.llmod(), namebuf.as_ptr()) };
     if val.is_null() {
         debug!("get_declared_value: {:?} value is null", name);
         None
index b8dd7273a8331df4ac0c1fec8dbbe3572c25cf2e..2a60dd17446717eae78d1a971c48dc81e6ee541a 100644 (file)
@@ -1512,7 +1512,7 @@ fn trans_unary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                           C_integral(llty, min, true), debug_loc);
                         with_cond(bcx, is_min, |bcx| {
                             let msg = InternedString::new(
-                                "attempted to negate with overflow");
+                                "attempt to negate with overflow");
                             controlflow::trans_fail(bcx, expr_info(expr), msg)
                         })
                     } else {
index 1e4a27481827dae8b84405efd1d4eb74696d0893..4980fad0cc37e676f3605bbcfdd667166e1681a7 100644 (file)
@@ -406,9 +406,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             C_str_slice(ccx, ty_name)
         }
         (_, "type_id") => {
-            let hash = ccx.tcx().hash_crate_independent(*substs.types.get(FnSpace, 0),
-                                                        &ccx.link_meta().crate_hash);
-            C_u64(ccx, hash)
+            C_u64(ccx, ccx.tcx().type_id_hash(*substs.types.get(FnSpace, 0)))
         }
         (_, "init_dropped") => {
             let tp_ty = *substs.types.get(FnSpace, 0);
@@ -640,28 +638,30 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         // This requires that atomic intrinsics follow a specific naming pattern:
         // "atomic_<operation>[_<ordering>]", and no ordering means SeqCst
         (_, name) if name.starts_with("atomic_") => {
+            use llvm::AtomicOrdering::*;
+
             let split: Vec<&str> = name.split('_').collect();
 
             let is_cxchg = split[1] == "cxchg" || split[1] == "cxchgweak";
             let (order, failorder) = match split.len() {
-                2 => (llvm::SequentiallyConsistent, llvm::SequentiallyConsistent),
+                2 => (SequentiallyConsistent, SequentiallyConsistent),
                 3 => match split[2] {
-                    "unordered" => (llvm::Unordered, llvm::Unordered),
-                    "relaxed" => (llvm::Monotonic, llvm::Monotonic),
-                    "acq"     => (llvm::Acquire, llvm::Acquire),
-                    "rel"     => (llvm::Release, llvm::Monotonic),
-                    "acqrel"  => (llvm::AcquireRelease, llvm::Acquire),
+                    "unordered" => (Unordered, Unordered),
+                    "relaxed" => (Monotonic, Monotonic),
+                    "acq"     => (Acquire, Acquire),
+                    "rel"     => (Release, Monotonic),
+                    "acqrel"  => (AcquireRelease, Acquire),
                     "failrelaxed" if is_cxchg =>
-                        (llvm::SequentiallyConsistent, llvm::Monotonic),
+                        (SequentiallyConsistent, Monotonic),
                     "failacq" if is_cxchg =>
-                        (llvm::SequentiallyConsistent, llvm::Acquire),
+                        (SequentiallyConsistent, Acquire),
                     _ => ccx.sess().fatal("unknown ordering in atomic intrinsic")
                 },
                 4 => match (split[2], split[3]) {
                     ("acq", "failrelaxed") if is_cxchg =>
-                        (llvm::Acquire, llvm::Monotonic),
+                        (Acquire, Monotonic),
                     ("acqrel", "failrelaxed") if is_cxchg =>
-                        (llvm::AcquireRelease, llvm::Monotonic),
+                        (AcquireRelease, Monotonic),
                     _ => ccx.sess().fatal("unknown ordering in atomic intrinsic")
                 },
                 _ => ccx.sess().fatal("Atomic intrinsic not in correct format"),
@@ -714,12 +714,12 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                 }
 
                 "fence" => {
-                    AtomicFence(bcx, order, llvm::CrossThread);
+                    AtomicFence(bcx, order, llvm::SynchronizationScope::CrossThread);
                     C_nil(ccx)
                 }
 
                 "singlethreadfence" => {
-                    AtomicFence(bcx, order, llvm::SingleThread);
+                    AtomicFence(bcx, order, llvm::SynchronizationScope::SingleThread);
                     C_nil(ccx)
                 }
 
index 2d1769b8637b30016dd615e053a83d0e14982869..9bfdb511c623c97f34974b9711b443978ffcea3b 100644 (file)
@@ -261,7 +261,23 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
 
             mir::TerminatorKind::Assert { ref cond, expected, ref msg, target, cleanup } => {
                 let cond = self.trans_operand(&bcx, cond).immediate();
-                let const_cond = common::const_to_opt_uint(cond).map(|c| c == 1);
+                let mut const_cond = common::const_to_opt_uint(cond).map(|c| c == 1);
+
+                // This case can currently arise only from functions marked
+                // with #[rustc_inherit_overflow_checks] and inlined from
+                // another crate (mostly core::num generic/#[inline] fns),
+                // while the current crate doesn't use overflow checks.
+                // NOTE: Unlike binops, negation doesn't have its own
+                // checked operation, just a comparison with the minimum
+                // value, so we have to check for the assert message.
+                if !bcx.ccx().check_overflow() {
+                    use rustc_const_math::ConstMathErr::Overflow;
+                    use rustc_const_math::Op::Neg;
+
+                    if let mir::AssertMessage::Math(Overflow(Neg)) = *msg {
+                        const_cond = Some(expected);
+                    }
+                }
 
                 // Don't translate the panic block if success if known.
                 if const_cond == Some(expected) {
index 8dc5e5f993fbe5122deba33712eb99aed3bf52a6..00db19d2739c3953d95615af8801e6169acb13ae 100644 (file)
@@ -824,11 +824,11 @@ pub fn const_scalar_binop(op: mir::BinOp,
             mir::BinOp::Gt | mir::BinOp::Ge => {
                 if is_float {
                     let cmp = base::bin_op_to_fcmp_predicate(op.to_hir_binop());
-                    llvm::ConstFCmp(cmp, lhs, rhs)
+                    llvm::LLVMConstFCmp(cmp, lhs, rhs)
                 } else {
                     let cmp = base::bin_op_to_icmp_predicate(op.to_hir_binop(),
                                                                 signed);
-                    llvm::ConstICmp(cmp, lhs, rhs)
+                    llvm::LLVMConstICmp(cmp, lhs, rhs)
                 }
             }
         }
index 0221232a77df5275a89754b15c3e39e5104ce411..8f723d288c9eb4718cb4bb77580396bbf122b4ac 100644 (file)
@@ -324,8 +324,8 @@ fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
                         machine::llelement_offset(bcx.ccx(), lltuplety, i);
 
                     let ops = unsafe {
-                        [llvm::LLVMDIBuilderCreateOpDeref(),
-                         llvm::LLVMDIBuilderCreateOpPlus(),
+                        [llvm::LLVMRustDIBuilderCreateOpDeref(),
+                         llvm::LLVMRustDIBuilderCreateOpPlus(),
                          byte_offset_of_var_in_tuple as i64]
                     };
 
@@ -450,10 +450,10 @@ fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
                     machine::llelement_offset(bcx.ccx(), llclosurety, i);
 
                 let ops = unsafe {
-                    [llvm::LLVMDIBuilderCreateOpDeref(),
-                     llvm::LLVMDIBuilderCreateOpPlus(),
+                    [llvm::LLVMRustDIBuilderCreateOpDeref(),
+                     llvm::LLVMRustDIBuilderCreateOpPlus(),
                      byte_offset_of_var_in_env as i64,
-                     llvm::LLVMDIBuilderCreateOpDeref()]
+                     llvm::LLVMRustDIBuilderCreateOpDeref()]
                 };
 
                 // The environment and the capture can each be indirect.
index 6ebc23884918976c19f4cfc1c220ed3ab3977a8f..97d65ce9c53614bf1a2600fd48e6c0fb1f15f3cc 100644 (file)
@@ -244,18 +244,46 @@ pub fn trans_rvalue_operand(&mut self,
                             }
                         }
                     }
-                    mir::CastKind::Misc if common::type_is_immediate(bcx.ccx(), operand.ty) => {
+                    mir::CastKind::Misc if common::type_is_fat_ptr(bcx.tcx(), operand.ty) => {
+                        let ll_cast_ty = type_of::immediate_type_of(bcx.ccx(), cast_ty);
+                        let ll_from_ty = type_of::immediate_type_of(bcx.ccx(), operand.ty);
+                        if let OperandValue::Pair(data_ptr, meta_ptr) = operand.val {
+                            if common::type_is_fat_ptr(bcx.tcx(), cast_ty) {
+                                let ll_cft = ll_cast_ty.field_types();
+                                let ll_fft = ll_from_ty.field_types();
+                                let data_cast = bcx.pointercast(data_ptr, ll_cft[0]);
+                                assert_eq!(ll_cft[1].kind(), ll_fft[1].kind());
+                                OperandValue::Pair(data_cast, meta_ptr)
+                            } else { // cast to thin-ptr
+                                // Cast of fat-ptr to thin-ptr is an extraction of data-ptr and
+                                // pointer-cast of that pointer to desired pointer type.
+                                let llval = bcx.pointercast(data_ptr, ll_cast_ty);
+                                OperandValue::Immediate(llval)
+                            }
+                        } else {
+                            bug!("Unexpected non-Pair operand")
+                        }
+                    }
+                    mir::CastKind::Misc => {
                         debug_assert!(common::type_is_immediate(bcx.ccx(), cast_ty));
                         let r_t_in = CastTy::from_ty(operand.ty).expect("bad input type for cast");
                         let r_t_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
                         let ll_t_in = type_of::immediate_type_of(bcx.ccx(), operand.ty);
                         let ll_t_out = type_of::immediate_type_of(bcx.ccx(), cast_ty);
-                        let llval = operand.immediate();
-                        let signed = if let CastTy::Int(IntTy::CEnum) = r_t_in {
+                        let (llval, signed) = if let CastTy::Int(IntTy::CEnum) = r_t_in {
                             let repr = adt::represent_type(bcx.ccx(), operand.ty);
-                            adt::is_discr_signed(&repr)
+                            let discr = match operand.val {
+                                OperandValue::Immediate(llval) => llval,
+                                OperandValue::Ref(llptr) => {
+                                    bcx.with_block(|bcx| {
+                                        adt::trans_get_discr(bcx, &repr, llptr, None, true)
+                                    })
+                                }
+                                OperandValue::Pair(..) => bug!("Unexpected Pair operand")
+                            };
+                            (discr, adt::is_discr_signed(&repr))
                         } else {
-                            operand.ty.is_signed()
+                            (operand.immediate(), operand.ty.is_signed())
                         };
 
                         let newval = match (r_t_in, r_t_out) {
@@ -304,26 +332,6 @@ pub fn trans_rvalue_operand(&mut self,
                         };
                         OperandValue::Immediate(newval)
                     }
-                    mir::CastKind::Misc => { // Casts from a fat-ptr.
-                        let ll_cast_ty = type_of::immediate_type_of(bcx.ccx(), cast_ty);
-                        let ll_from_ty = type_of::immediate_type_of(bcx.ccx(), operand.ty);
-                        if let OperandValue::Pair(data_ptr, meta_ptr) = operand.val {
-                            if common::type_is_fat_ptr(bcx.tcx(), cast_ty) {
-                                let ll_cft = ll_cast_ty.field_types();
-                                let ll_fft = ll_from_ty.field_types();
-                                let data_cast = bcx.pointercast(data_ptr, ll_cft[0]);
-                                assert_eq!(ll_cft[1].kind(), ll_fft[1].kind());
-                                OperandValue::Pair(data_cast, meta_ptr)
-                            } else { // cast to thin-ptr
-                                // Cast of fat-ptr to thin-ptr is an extraction of data-ptr and
-                                // pointer-cast of that pointer to desired pointer type.
-                                let llval = bcx.pointercast(data_ptr, ll_cast_ty);
-                                OperandValue::Immediate(llval)
-                            }
-                        } else {
-                            bug!("Unexpected non-Pair operand")
-                        }
-                    }
                 };
                 let operand = OperandRef {
                     val: val,
index 96a05f11bfd119e65fcecc4b9b7a6e7c92bf81b6..e9aacaa0f954f2e4fc20daa8d50ba442bcabc0b8 100644 (file)
@@ -125,7 +125,9 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
             if ccx.shared().translation_items().borrow().contains(&trans_item) {
                 attributes::from_fn_attrs(ccx, attrs, lldecl);
-                llvm::SetLinkage(lldecl, llvm::ExternalLinkage);
+                unsafe {
+                    llvm::LLVMSetLinkage(lldecl, llvm::ExternalLinkage);
+                }
             } else {
                 // FIXME: #34151
                 // Normally, getting here would indicate a bug in trans::collector,
index 0ee4c031adccae61e11af4ed9fc313c6dc3e8ef4..d0e00a6d593a5edf18742ebdae8156e467ac9ea0 100644 (file)
@@ -166,7 +166,7 @@ fn predefine_static(ccx: &CrateContext<'a, 'tcx>,
                         &format!("symbol `{}` is already defined", symbol_name))
                 });
 
-                llvm::SetLinkage(g, linkage);
+                unsafe { llvm::LLVMSetLinkage(g, linkage) };
             }
 
             item => bug!("predefine_static: expected static, found {:?}", item)
@@ -208,7 +208,7 @@ fn predefine_fn(ccx: &CrateContext<'a, 'tcx>,
                 ref attrs, node: hir::ImplItemKind::Method(..), ..
             }) => {
                 let lldecl = declare::declare_fn(ccx, symbol_name, mono_ty);
-                llvm::SetLinkage(lldecl, linkage);
+                unsafe { llvm::LLVMSetLinkage(lldecl, linkage) };
                 base::set_link_section(ccx, lldecl, attrs);
                 if linkage == llvm::LinkOnceODRLinkage ||
                    linkage == llvm::WeakODRLinkage {
@@ -245,7 +245,7 @@ fn predefine_drop_glue(ccx: &CrateContext<'a, 'tcx>,
 
         assert!(declare::get_defined_value(ccx, symbol_name).is_none());
         let llfn = declare::declare_cfn(ccx, symbol_name, llfnty);
-        llvm::SetLinkage(llfn, linkage);
+        unsafe { llvm::LLVMSetLinkage(llfn, linkage) };
         if linkage == llvm::LinkOnceODRLinkage ||
            linkage == llvm::WeakODRLinkage {
             llvm::SetUniqueComdat(ccx.llmod(), llfn);
index 001cd197e60b8a8df178068723062dc82b51c0df..d191591e082adedef8e9d7a0bfd00cd3cef875bd 100644 (file)
@@ -36,7 +36,7 @@ pub struct Type {
 impl fmt::Debug for Type {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.write_str(&llvm::build_string(|s| unsafe {
-            llvm::LLVMWriteTypeToString(self.to_ref(), s);
+            llvm::LLVMRustWriteTypeToString(self.to_ref(), s);
         }).expect("non-UTF8 type description from LLVM"))
     }
 }
@@ -72,7 +72,7 @@ pub fn nil(ccx: &CrateContext) -> Type {
     }
 
     pub fn metadata(ccx: &CrateContext) -> Type {
-        ty!(llvm::LLVMMetadataTypeInContext(ccx.llcx()))
+        ty!(llvm::LLVMRustMetadataTypeInContext(ccx.llcx()))
     }
 
     pub fn i1(ccx: &CrateContext) -> Type {
@@ -208,7 +208,7 @@ pub fn vtable_ptr(ccx: &CrateContext) -> Type {
 
     pub fn kind(&self) -> TypeKind {
         unsafe {
-            llvm::LLVMGetTypeKind(self.to_ref())
+            llvm::LLVMRustGetTypeKind(self.to_ref())
         }
     }
 
index 00b316cc420ee8f035fe6616cf56b8c3e479fc1f..79e0c11515fc49f34fe6cb5ed716a2fd8d1378a6 100644 (file)
@@ -23,7 +23,7 @@
 impl fmt::Debug for Value {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.write_str(&llvm::build_string(|s| unsafe {
-            llvm::LLVMWriteValueToString(self.0, s);
+            llvm::LLVMRustWriteValueToString(self.0, s);
         }).expect("nun-UTF8 value description from LLVM"))
     }
 }
index 3b2bca4ab391225f9e477195a248be95a9b5eefd..b4e9fb5c65bb3576417b53469e454c262a249830 100644 (file)
@@ -310,8 +310,12 @@ pub fn opt_ast_region_to_region(&self,
             None => match rscope.anon_regions(default_span, 1) {
                 Ok(rs) => rs[0],
                 Err(params) => {
-                    let mut err = struct_span_err!(self.tcx().sess, default_span, E0106,
-                                                   "missing lifetime specifier");
+                    let ampersand_span = Span { hi: default_span.lo, ..default_span};
+
+                    let mut err = struct_span_err!(self.tcx().sess, ampersand_span, E0106,
+                                                 "missing lifetime specifier");
+                    err.span_label(ampersand_span, &format!("expected lifetime parameter"));
+
                     if let Some(params) = params {
                         report_elision_failure(&mut err, params);
                     }
@@ -1075,8 +1079,10 @@ fn ast_ty_to_trait_ref(&self,
                         Ok((trait_ref, projection_bounds))
                     }
                     _ => {
-                        span_err!(self.tcx().sess, ty.span, E0172,
-                                  "expected a reference to a trait");
+                        struct_span_err!(self.tcx().sess, ty.span, E0172,
+                                  "expected a reference to a trait")
+                            .span_label(ty.span, &format!("expected a trait"))
+                            .emit();
                         Err(ErrorReported)
                     }
                 }
@@ -1086,6 +1092,7 @@ fn ast_ty_to_trait_ref(&self,
                                                "expected a path on the left-hand side \
                                                 of `+`, not `{}`",
                                                pprust::ty_to_string(ty));
+                err.span_label(ty.span, &format!("expected a path"));
                 let hi = bounds.iter().map(|x| match *x {
                     hir::TraitTyParamBound(ref tr, _) => tr.span.hi,
                     hir::RegionTyParamBound(ref r) => r.span.hi,
@@ -1208,10 +1215,12 @@ fn report_ambiguous_associated_type(&self,
                                         type_str: &str,
                                         trait_str: &str,
                                         name: &str) {
-        span_err!(self.tcx().sess, span, E0223,
-                  "ambiguous associated type; specify the type using the syntax \
-                   `<{} as {}>::{}`",
-                  type_str, trait_str, name);
+        struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type")
+            .span_label(span, &format!("ambiguous associated type"))
+            .note(&format!("specify the type using the syntax `<{} as {}>::{}`",
+                  type_str, trait_str, name))
+            .emit();
+
     }
 
     // Search for a bound on a type parameter which includes the associated item
@@ -2088,8 +2097,11 @@ pub fn conv_existential_bounds_from_partitioned_bounds(&self,
 
         if !trait_bounds.is_empty() {
             let b = &trait_bounds[0];
-            span_err!(self.tcx().sess, b.trait_ref.path.span, E0225,
-                      "only the builtin traits can be used as closure or object bounds");
+            let span = b.trait_ref.path.span;
+            struct_span_err!(self.tcx().sess, span, E0225,
+                             "only the builtin traits can be used as closure or object bounds")
+                .span_label(span, &format!("non-builtin trait used as bounds"))
+                .emit();
         }
 
         let region_bound =
@@ -2248,27 +2260,50 @@ fn check_type_argument_count(tcx: TyCtxt, span: Span, supplied: usize,
         } else {
             "expected"
         };
-        span_err!(tcx.sess, span, E0243,
-                  "wrong number of type arguments: {} {}, found {}",
-                  expected, required, supplied);
+        struct_span_err!(tcx.sess, span, E0243, "wrong number of type arguments")
+            .span_label(
+                span,
+                &format!("{} {} type arguments, found {}", expected, required, supplied)
+            )
+            .emit();
     } else if supplied > accepted {
-        let expected = if required < accepted {
-            "expected at most"
+        let expected = if required == 0 {
+            "expected no".to_string()
+        } else if required < accepted {
+            format!("expected at most {}", accepted)
         } else {
-            "expected"
+            format!("expected {}", accepted)
         };
-        span_err!(tcx.sess, span, E0244,
-                  "wrong number of type arguments: {} {}, found {}",
-                  expected,
-                  accepted,
-                  supplied);
+
+        struct_span_err!(tcx.sess, span, E0244, "wrong number of type arguments")
+            .span_label(
+                span,
+                &format!("{} type arguments, found {}", expected, supplied)
+            )
+            .emit();
     }
 }
 
 fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected: usize) {
-    span_err!(tcx.sess, span, E0107,
-              "wrong number of lifetime parameters: expected {}, found {}",
-              expected, number);
+    let label = if number < expected {
+        if expected == 1 {
+            format!("expected {} lifetime parameter", expected)
+        } else {
+            format!("expected {} lifetime parameters", expected)
+        }
+    } else {
+        let additional = number - expected;
+        if additional == 1 {
+            "unexpected lifetime parameter".to_string()
+        } else {
+            format!("{} unexpected lifetime parameters", additional)
+        }
+    };
+    struct_span_err!(tcx.sess, span, E0107,
+                     "wrong number of lifetime parameters: expected {}, found {}",
+                     expected, number)
+        .span_label(span, &label)
+        .emit();
 }
 
 // A helper struct for conveniently grouping a set of bounds which we pass to
index aae6e3ad36dfe7ee2ba7b1ec173cd2d3f8193a82..fe68690d4e97447efbc826717314234bbffb86ec 100644 (file)
@@ -93,13 +93,12 @@ pub fn check_pat(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>) {
                         end.span
                     };
 
-                    // Note: spacing here is intentional, we want a space before "start" and "end".
-                    span_err!(tcx.sess, span, E0029,
-                              "only char and numeric types are allowed in range patterns\n \
-                               start type: {}\n end type: {}",
-                              self.ty_to_string(lhs_ty),
-                              self.ty_to_string(rhs_ty)
-                    );
+                    struct_span_err!(tcx.sess, span, E0029,
+                        "only char and numeric types are allowed in range patterns")
+                        .span_label(span, &format!("ranges require char or numeric types"))
+                        .note(&format!("start type: {}", self.ty_to_string(lhs_ty)))
+                        .note(&format!("end type: {}", self.ty_to_string(rhs_ty)))
+                        .emit();
                     return;
                 }
 
@@ -700,9 +699,11 @@ pub fn check_struct_pat_fields(&self,
             for field in variant.fields
                 .iter()
                 .filter(|field| !used_fields.contains_key(&field.name)) {
-                span_err!(tcx.sess, span, E0027,
-                    "pattern does not mention field `{}`",
-                    field.name);
+                struct_span_err!(tcx.sess, span, E0027,
+                                "pattern does not mention field `{}`",
+                                field.name)
+                                .span_label(span, &format!("missing field `{}`", field.name))
+                                .emit();
             }
         }
     }
index 3c176744fca592b0dd766a9a3db378223bd0cfc4..265422468fe2a1c4a18b6ca9f790f005d2f539d5 100644 (file)
@@ -54,9 +54,11 @@ fn next(&mut self) -> Option<Self::Item> {
 
         if self.steps.len() == tcx.sess.recursion_limit.get() {
             // We've reached the recursion limit, error gracefully.
-            span_err!(tcx.sess, self.span, E0055,
+            struct_span_err!(tcx.sess, self.span, E0055,
                       "reached the recursion limit while auto-dereferencing {:?}",
-                      self.cur_ty);
+                      self.cur_ty)
+                      .span_label(self.span, &format!("deref recursion limit reached"))
+                      .emit();
             return None;
         }
 
index bd2c05ba66d47188d77729c08c5cf874832c79b9..e73c3aa352b5605beec6fe6d8b1f164554360fbf 100644 (file)
@@ -28,7 +28,9 @@
 /// method that is called)
 pub fn check_legal_trait_for_method_call(ccx: &CrateCtxt, span: Span, trait_id: DefId) {
     if ccx.tcx.lang_items.drop_trait() == Some(trait_id) {
-        span_err!(ccx.tcx.sess, span, E0040, "explicit use of destructor method");
+        struct_span_err!(ccx.tcx.sess, span, E0040, "explicit use of destructor method")
+            .span_label(span, &format!("call to destructor method"))
+            .emit();
     }
 }
 
index 9844377d0bd32f5241c1e0cb948f48597c1d5673..b971ae02cd0bd27a87905137df7540a80142257b 100644 (file)
@@ -59,19 +59,33 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         (&ty::ExplicitSelfCategory::Static,
          &ty::ExplicitSelfCategory::Static) => {}
         (&ty::ExplicitSelfCategory::Static, _) => {
-            span_err!(tcx.sess, impl_m_span, E0185,
+            let mut err = struct_span_err!(tcx.sess, impl_m_span, E0185,
                 "method `{}` has a `{}` declaration in the impl, \
                         but not in the trait",
                         trait_m.name,
                         impl_m.explicit_self);
+            err.span_label(impl_m_span, &format!("`{}` used in impl",
+                                                 impl_m.explicit_self));
+            if let Some(span) = tcx.map.span_if_local(trait_m.def_id) {
+                err.span_label(span, &format!("trait declared without `{}`",
+                                              impl_m.explicit_self));
+            }
+            err.emit();
             return;
         }
         (_, &ty::ExplicitSelfCategory::Static) => {
-            span_err!(tcx.sess, impl_m_span, E0186,
+            let mut err = struct_span_err!(tcx.sess, impl_m_span, E0186,
                 "method `{}` has a `{}` declaration in the trait, \
                         but not in the impl",
                         trait_m.name,
                         trait_m.explicit_self);
+            err.span_label(impl_m_span, &format!("expected `{}` in impl",
+                                                  trait_m.explicit_self));
+            if let Some(span) = tcx.map.span_if_local(trait_m.def_id) {
+                err.span_label(span, & format!("`{}` used in trait",
+                                               trait_m.explicit_self));
+            }
+            err.emit();
             return;
         }
         _ => {
index 346449d0a51331465bde2b99b5eec3048bb74e7c..54521782474fe05ac1e8b15ae5e0fec19a193def 100644 (file)
@@ -162,26 +162,34 @@ pub fn report_method_error(&self,
                     },
                     rcvr_ty);
 
-                // If the item has the name of a field, give a help note
-                if let (&ty::TyStruct(def, substs), Some(expr)) = (&rcvr_ty.sty, rcvr_expr) {
-                    if let Some(field) = def.struct_variant().find_field_named(item_name) {
-                        let expr_string = match tcx.sess.codemap().span_to_snippet(expr.span) {
-                            Ok(expr_string) => expr_string,
-                            _ => "s".into() // Default to a generic placeholder for the
-                                            // expression when we can't generate a string
-                                            // snippet
-                        };
-
-                        let field_ty = field.ty(tcx, substs);
-
-                        if self.is_fn_ty(&field_ty, span) {
-                            err.span_note(span,
-                                          &format!("use `({0}.{1})(...)` if you meant to call \
-                                                   the function stored in the `{1}` field",
-                                                   expr_string, item_name));
-                        } else {
-                            err.span_note(span, &format!("did you mean to write `{0}.{1}`?",
-                                                         expr_string, item_name));
+                // If the method name is the name of a field with a function or closure type,
+                // give a helping note that it has to be called as (x.f)(...).
+                if let Some(expr) = rcvr_expr {
+                    for (ty, _) in self.autoderef(span, rcvr_ty) {
+                        if let ty::TyStruct(def, substs) = ty.sty {
+                            if let Some(field) = def.struct_variant().find_field_named(item_name) {
+                                let snippet = tcx.sess.codemap().span_to_snippet(expr.span);
+                                let expr_string = match snippet {
+                                    Ok(expr_string) => expr_string,
+                                    _ => "s".into() // Default to a generic placeholder for the
+                                                    // expression when we can't generate a
+                                                    // string snippet
+                                };
+
+                                let field_ty = field.ty(tcx, substs);
+
+                                if self.is_fn_ty(&field_ty, span) {
+                                    err.span_note(span, &format!(
+                                        "use `({0}.{1})(...)` if you meant to call the function \
+                                         stored in the `{1}` field",
+                                        expr_string, item_name));
+                                } else {
+                                    err.span_note(span, &format!(
+                                        "did you mean to write `{0}.{1}`?",
+                                        expr_string, item_name));
+                                }
+                                break;
+                            }
                         }
                     }
                 }
index 6062bd048b3d27f8972edfbdce5efa766c448aab..4bb36aa639c541b1e0ae46517a27b654b46d4f40 100644 (file)
@@ -847,7 +847,9 @@ fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
             // good
         }
         hir::Constness::Const => {
-            span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
+            struct_span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const")
+                .span_label(span, &format!("trait fns cannot be const"))
+                .emit()
         }
     }
 }
@@ -993,7 +995,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     // Check existing impl methods to see if they are both present in trait
     // and compatible with trait signature
     for impl_item in impl_items {
-        let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
+        let ty_impl_item = tcx.impl_or_trait_item(tcx.map.local_def_id(impl_item.id));
         let ty_trait_item = trait_items.iter()
             .find(|ac| ac.name() == ty_impl_item.name());
 
@@ -1014,11 +1016,18 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                            trait_const,
                                            &impl_trait_ref);
                     } else {
-                        span_err!(tcx.sess, impl_item.span, E0323,
+                         let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
                                   "item `{}` is an associated const, \
                                   which doesn't match its trait `{:?}`",
                                   impl_const.name,
-                                  impl_trait_ref)
+                                  impl_trait_ref);
+                         err.span_label(impl_item.span, &format!("does not match trait"));
+                         // We can only get the spans from local trait definition
+                         // Same for E0324 and E0325
+                         if let Some(trait_span) = tcx.map.span_if_local(ty_trait_item.def_id()) {
+                            err.span_label(trait_span, &format!("original trait requirement"));
+                         }
+                         err.emit()
                     }
                 }
                 hir::ImplItemKind::Method(ref sig, ref body) => {
@@ -1037,11 +1046,16 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                             &trait_method,
                                             &impl_trait_ref);
                     } else {
-                        span_err!(tcx.sess, impl_item.span, E0324,
+                        let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
                                   "item `{}` is an associated method, \
                                   which doesn't match its trait `{:?}`",
                                   impl_method.name,
-                                  impl_trait_ref)
+                                  impl_trait_ref);
+                         err.span_label(impl_item.span, &format!("does not match trait"));
+                         if let Some(trait_span) = tcx.map.span_if_local(ty_trait_item.def_id()) {
+                            err.span_label(trait_span, &format!("original trait requirement"));
+                         }
+                         err.emit()
                     }
                 }
                 hir::ImplItemKind::Type(_) => {
@@ -1055,11 +1069,16 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                             overridden_associated_type = Some(impl_item);
                         }
                     } else {
-                        span_err!(tcx.sess, impl_item.span, E0325,
+                        let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
                                   "item `{}` is an associated type, \
                                   which doesn't match its trait `{:?}`",
                                   impl_type.name,
-                                  impl_trait_ref)
+                                  impl_trait_ref);
+                         err.span_label(impl_item.span, &format!("does not match trait"));
+                         if let Some(trait_span) = tcx.map.span_if_local(ty_trait_item.def_id()) {
+                            err.span_label(trait_span, &format!("original trait requirement"));
+                         }
+                         err.emit()
                     }
                 }
             }
@@ -1117,11 +1136,16 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     }
 
     if !missing_items.is_empty() {
-        span_err!(tcx.sess, impl_span, E0046,
+        struct_span_err!(tcx.sess, impl_span, E0046,
             "not all trait items implemented, missing: `{}`",
             missing_items.iter()
                   .map(|name| name.to_string())
                   .collect::<Vec<_>>().join("`, `"))
+            .span_label(impl_span, &format!("missing `{}` in implementation",
+                missing_items.iter()
+                    .map(|name| name.to_string())
+                    .collect::<Vec<_>>().join("`, `"))
+            ).emit();
     }
 
     if !invalidated_items.is_empty() {
@@ -1251,8 +1275,9 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0081,
                     "discriminant value `{}` already exists", disr_vals[i]);
                 let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
-                span_note!(&mut err, ccx.tcx.map.span(variant_i_node_id),
-                    "conflicting discriminant here");
+                err.span_label(ccx.tcx.map.span(variant_i_node_id),
+                               &format!("first use of `{}`", disr_vals[i]));
+                err.span_label(v.span , &format!("enum already has `{}`", disr_vals[i]));
                 err.emit();
             }
             disr_vals.push(current_disr_val);
@@ -2384,6 +2409,12 @@ fn parameter_count_error<'tcx>(sess: &Session, sp: Span, fn_inputs: &[Ty<'tcx>],
                     arg_count,
                     if arg_count == 1 {" was"} else {"s were"}),
                 error_code);
+
+            err.span_label(sp, &format!("expected {}{} parameter{}",
+                                        if variadic {"at least "} else {""},
+                                        expected_count,
+                                        if expected_count == 1 {""} else {"s"}));
+
             let input_types = fn_inputs.iter().map(|i| format!("{:?}", i)).collect::<Vec<String>>();
             if input_types.len() > 0 {
                 err.note(&format!("the following parameter type{} expected: {}",
@@ -3063,6 +3094,8 @@ fn check_expr_struct_fields(&self,
             remaining_fields.insert(field.name, field);
         }
 
+        let mut seen_fields = FnvHashMap();
+
         let mut error_happened = false;
 
         // Typecheck each field.
@@ -3071,13 +3104,25 @@ fn check_expr_struct_fields(&self,
 
             if let Some(v_field) = remaining_fields.remove(&field.name.node) {
                 expected_field_type = self.field_ty(field.span, v_field, substs);
+
+                seen_fields.insert(field.name.node, field.span);
             } else {
                 error_happened = true;
                 expected_field_type = tcx.types.err;
                 if let Some(_) = variant.find_field_named(field.name.node) {
-                    span_err!(self.tcx.sess, field.name.span, E0062,
-                        "field `{}` specified more than once",
-                        field.name.node);
+                    let mut err = struct_span_err!(self.tcx.sess,
+                                                field.name.span,
+                                                E0062,
+                                                "field `{}` specified more than once",
+                                                field.name.node);
+
+                    err.span_label(field.name.span, &format!("used more than once"));
+
+                    if let Some(prev_span) = seen_fields.get(&field.name.node) {
+                        err.span_label(*prev_span, &format!("first use of `{}`", field.name.node));
+                    }
+
+                    err.emit();
                 } else {
                     self.report_unknown_field(adt_ty, variant, field, ast_fields);
                 }
@@ -3147,9 +3192,12 @@ pub fn check_struct_path(&self,
         };
         if variant.is_none() || variant.unwrap().kind == ty::VariantKind::Tuple {
             // Reject tuple structs for now, braced and unit structs are allowed.
-            span_err!(self.tcx.sess, span, E0071,
-                      "`{}` does not name a struct or a struct variant",
-                      pprust::path_to_string(path));
+            struct_span_err!(self.tcx.sess, path.span, E0071,
+                             "`{}` does not name a struct or a struct variant",
+                             pprust::path_to_string(path))
+                .span_label(path.span, &format!("not a struct"))
+                .emit();
+
             return None;
         }
 
@@ -3383,8 +3431,10 @@ fn check_expr_with_expectation_and_lvalue_pref(&self,
                             // FIXME(#32730) propagate obligations
                             .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()));
                         if eq_result.is_err() {
-                            span_err!(tcx.sess, expr.span, E0069,
-                                      "`return;` in a function whose return type is not `()`");
+                            struct_span_err!(tcx.sess, expr.span, E0069,
+                                     "`return;` in a function whose return type is not `()`")
+                                .span_label(expr.span, &format!("return type is not ()"))
+                                .emit();
                         }
                     }
                 }
@@ -3392,8 +3442,10 @@ fn check_expr_with_expectation_and_lvalue_pref(&self,
                     if let Some(ref e) = *expr_opt {
                         self.check_expr(&e);
                     }
-                    span_err!(tcx.sess, expr.span, E0166,
-                        "`return` in a function declared as diverging");
+                    struct_span_err!(tcx.sess, expr.span, E0166,
+                        "`return` in a function declared as diverging")
+                        .span_label(expr.span, &format!("diverging function cannot return"))
+                        .emit();
                 }
             }
             self.write_ty(id, self.next_diverging_ty_var());
index d02f87d0b9cd64236700279cd10bfc1744f0c7af..63487683ec3b990feff4aa0fc1687b465cc916f0 100644 (file)
@@ -176,11 +176,15 @@ fn check_overloaded_binop(&self,
                 // error types are considered "builtin"
                 if !lhs_ty.references_error() {
                     if let IsAssign::Yes = is_assign {
-                        span_err!(self.tcx.sess, lhs_expr.span, E0368,
-                                  "binary assignment operation `{}=` \
-                                   cannot be applied to type `{}`",
-                                  op.node.as_str(),
-                                  lhs_ty);
+                        struct_span_err!(self.tcx.sess, lhs_expr.span, E0368,
+                                         "binary assignment operation `{}=` \
+                                          cannot be applied to type `{}`",
+                                         op.node.as_str(),
+                                         lhs_ty)
+                            .span_label(lhs_expr.span,
+                                        &format!("cannot use `{}=` on type `{}`",
+                                        op.node.as_str(), lhs_ty))
+                            .emit();
                     } else {
                         let mut err = struct_span_err!(self.tcx.sess, lhs_expr.span, E0369,
                             "binary operation `{}` cannot be applied to type `{}`",
index 9786132dc537b53c57c0a4b47abde6fe863536ac..42893e40024e891aa14eb5ec8dd7684f3a93edb8 100644 (file)
@@ -441,13 +441,19 @@ fn report_error(&self, e: FixupError) {
         if !self.tcx.sess.has_errors() {
             match self.reason {
                 ResolvingExpr(span) => {
-                    span_err!(self.tcx.sess, span, E0101,
-                        "cannot determine a type for this expression: {}", e);
+                    struct_span_err!(
+                        self.tcx.sess, span, E0101,
+                        "cannot determine a type for this expression: {}", e)
+                        .span_label(span, &format!("cannot resolve type of expression"))
+                        .emit();
                 }
 
                 ResolvingLocal(span) => {
-                    span_err!(self.tcx.sess, span, E0102,
-                        "cannot determine a type for this local variable: {}", e);
+                    struct_span_err!(
+                        self.tcx.sess, span, E0102,
+                        "cannot determine a type for this local variable: {}", e)
+                        .span_label(span, &format!("cannot resolve type of variable"))
+                        .emit();
                 }
 
                 ResolvingPattern(span) => {
index 198e9afd5e12c77f1604d753ba612ba8414ad38c..cdf2ca14d4c78366a4a8284d9ac63eace14c2b01 100644 (file)
@@ -249,8 +249,17 @@ fn populate_destructors(&self) {
                     if let Some(impl_node_id) = tcx.map.as_local_node_id(impl_did) {
                         match tcx.map.find(impl_node_id) {
                             Some(hir_map::NodeItem(item)) => {
-                                span_err!(tcx.sess, item.span, E0120,
-                                          "the Drop trait may only be implemented on structures");
+                                let span = match item.node {
+                                    ItemImpl(_, _, _, _, ref ty, _) => {
+                                        ty.span
+                                    },
+                                    _ => item.span
+                                };
+                                struct_span_err!(tcx.sess, span, E0120,
+                                    "the Drop trait may only be implemented on structures")
+                                    .span_label(span,
+                                                &format!("implementing Drop requires a struct"))
+                                    .emit();
                             }
                             _ => {
                                 bug!("didn't find impl in ast map");
@@ -258,7 +267,7 @@ fn populate_destructors(&self) {
                         }
                     } else {
                         bug!("found external impl of Drop trait on \
-                              :omething other than a struct");
+                              something other than a struct");
                     }
                 }
             }
@@ -302,24 +311,36 @@ fn check_implementations_of_copy(&self) {
             match param_env.can_type_implement_copy(tcx, self_type, span) {
                 Ok(()) => {}
                 Err(CopyImplementationError::InfrigingField(name)) => {
-                       span_err!(tcx.sess, span, E0204,
-                                 "the trait `Copy` may not be \
-                                          implemented for this type; field \
-                                          `{}` does not implement `Copy`",
-                                         name)
+                       struct_span_err!(tcx.sess, span, E0204,
+                                 "the trait `Copy` may not be implemented for \
+                                 this type")
+                           .span_label(span, &format!(
+                                 "field `{}` does not implement `Copy`", name)
+                               )
+                           .emit()
+
                 }
                 Err(CopyImplementationError::InfrigingVariant(name)) => {
-                       span_err!(tcx.sess, span, E0205,
+                       struct_span_err!(tcx.sess, span, E0205,
                                  "the trait `Copy` may not be \
-                                          implemented for this type; variant \
+                                          implemented for this type")
+                           .span_label(span, &format!("variant \
                                           `{}` does not implement `Copy`",
-                                         name)
+                                         name))
+                           .emit()
                 }
                 Err(CopyImplementationError::NotAnAdt) => {
-                       span_err!(tcx.sess, span, E0206,
-                                 "the trait `Copy` may not be implemented \
-                                  for this type; type is not a structure or \
-                                  enumeration")
+                    let item = tcx.map.expect_item(impl_node_id);
+                    let span = if let ItemImpl(_, _, _, _, ref ty, _) = item.node {
+                        ty.span
+                    } else {
+                        span
+                    };
+
+                    struct_span_err!(tcx.sess, span, E0206,
+                                     "the trait `Copy` may not be implemented for this type")
+                        .span_label(span, &format!("type is not a structure or enumeration"))
+                        .emit();
                 }
                 Err(CopyImplementationError::HasDestructor) => {
                     span_err!(tcx.sess, span, E0184,
index 15d4026254fa57ec1c8f2ee03cb25e99c81916a9..e426f0cb643b7ab99159ed0ec331e438f5b23514 100644 (file)
@@ -33,10 +33,12 @@ struct OrphanChecker<'cx, 'tcx:'cx> {
 impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
     fn check_def_id(&self, item: &hir::Item, def_id: DefId) {
         if def_id.krate != LOCAL_CRATE {
-            span_err!(self.tcx.sess, item.span, E0116,
+            struct_span_err!(self.tcx.sess, item.span, E0116,
                       "cannot define inherent `impl` for a type outside of the \
-                       crate where the type is defined; define and implement \
-                       a trait or new type instead");
+                       crate where the type is defined")
+                .span_label(item.span, &format!("impl for type defined outside of crate."))
+                .span_note(item.span, &format!("define and implement a trait or new type instead"))
+                .emit();
         }
     }
 
@@ -66,7 +68,7 @@ fn check_primitive_impl(&self,
     fn check_item(&self, item: &hir::Item) {
         let def_id = self.tcx.map.local_def_id(item.id);
         match item.node {
-            hir::ItemImpl(_, _, _, None, _, _) => {
+            hir::ItemImpl(_, _, _, None, ref ty, _) => {
                 // For inherent impls, self type must be a nominal type
                 // defined in this crate.
                 debug!("coherence2::orphan check: inherent impl {}",
@@ -209,11 +211,11 @@ fn check_item(&self, item: &hir::Item) {
                         return;
                     }
                     _ => {
-                        struct_span_err!(self.tcx.sess, item.span, E0118,
+                        struct_span_err!(self.tcx.sess, ty.span, E0118,
                                          "no base type found for inherent implementation")
-                        .span_help(item.span,
-                                   "either implement a trait on it or create a newtype to wrap it \
-                                    instead")
+                        .span_label(ty.span, &format!("impl requires a base type"))
+                        .note(&format!("either implement a trait on it or create a newtype \
+                                        to wrap it instead"))
                         .emit();
                         return;
                     }
@@ -228,12 +230,14 @@ fn check_item(&self, item: &hir::Item) {
                 match traits::orphan_check(self.tcx, def_id) {
                     Ok(()) => { }
                     Err(traits::OrphanCheckErr::NoLocalInputType) => {
-                        span_err!(
+                        struct_span_err!(
                             self.tcx.sess, item.span, E0117,
-                            "the impl does not reference any \
-                             types defined in this crate; \
-                             only traits defined in the current crate can be \
-                             implemented for arbitrary types");
+                             "only traits defined in the current crate can be \
+                             implemented for arbitrary types")
+                        .span_label(item.span, &format!("impl doesn't use types inside crate"))
+                        .note(&format!("the impl does not reference any \
+                                        types defined in this crate"))
+                        .emit();
                         return;
                     }
                     Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => {
index dcaa5cfb20a46ff73a8c8f3509ec0bce51be717d..54bd141304d7816e21966f600a6c7c3878e1096f 100644 (file)
@@ -141,12 +141,18 @@ fn visit_item(&mut self, item: &'v hir::Item) {
                         self.tcx.sess, self.tcx.span_of_impl(impl_def_id).unwrap(), E0119,
                         "conflicting implementations of trait `{}`{}:",
                         overlap.trait_desc,
-                        overlap.self_desc.map_or(String::new(),
-                                                 |ty| format!(" for type `{}`", ty)));
+                        overlap.self_desc.clone().map_or(String::new(),
+                                                         |ty| format!(" for type `{}`", ty)));
 
                     match self.tcx.span_of_impl(overlap.with_impl) {
                         Ok(span) => {
-                            err.span_note(span, "conflicting implementation is here:");
+                            err.span_label(span,
+                                           &format!("first implementation here"));
+                            err.span_label(self.tcx.span_of_impl(impl_def_id).unwrap(),
+                                           &format!("conflicting implementation{}",
+                                                    overlap.self_desc
+                                                        .map_or(String::new(),
+                                                                |ty| format!(" for `{}`", ty))));
                         }
                         Err(cname) => {
                             err.note(&format!("conflicting implementation in crate `{}`",
index 9ed95fd5009bc31705eed8ad2ab9c553a2a489fe..f0ce4f6d2ec4225f9a022543cb8ca9ff6959cf6d 100644 (file)
@@ -60,8 +60,6 @@
 
 use astconv::{AstConv, ast_region_to_region, Bounds, PartitionedBounds, partition_bounds};
 use lint;
-use hir::def::Def;
-use hir::def_id::DefId;
 use constrained_type_params as ctp;
 use middle::lang_items::SizedTraitLangItem;
 use middle::const_val::ConstVal;
@@ -74,7 +72,6 @@
 use rustc::ty::util::IntTypeExt;
 use rscope::*;
 use rustc::dep_graph::DepNode;
-use rustc::hir::map as hir_map;
 use util::common::{ErrorReported, MemoizationMap};
 use util::nodemap::{NodeMap, FnvHashMap};
 use {CrateCtxt, write_ty_to_tcx};
@@ -91,9 +88,9 @@
 use syntax::ptr::P;
 use syntax_pos::Span;
 
-use rustc::hir::{self, PatKind};
-use rustc::hir::intravisit;
-use rustc::hir::print as pprust;
+use rustc::hir::{self, intravisit, map as hir_map, print as pprust};
+use rustc::hir::def::Def;
+use rustc::hir::def_id::DefId;
 
 ///////////////////////////////////////////////////////////////////////////
 // Main entry point
@@ -187,6 +184,7 @@ fn report_cycle(&self,
 
         let mut err = struct_span_err!(tcx.sess, span, E0391,
             "unsupported cyclic reference between types/traits detected");
+        err.span_label(span, &format!("cyclic reference"));
 
         match cycle[0] {
             AstConvRequest::GetItemTypeScheme(def_id) |
@@ -369,8 +367,13 @@ fn ty_infer(&self,
                 _substs: Option<&mut Substs<'tcx>>,
                 _space: Option<ParamSpace>,
                 span: Span) -> Ty<'tcx> {
-        span_err!(self.tcx().sess, span, E0121,
-                  "the type placeholder `_` is not allowed within types on item signatures");
+        struct_span_err!(
+            self.tcx().sess,
+            span,
+            E0121,
+            "the type placeholder `_` is not allowed within types on item signatures"
+        ).span_label(span, &format!("not allowed in type signatures"))
+        .emit();
         self.tcx().types.err
     }
 
@@ -772,9 +775,10 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
                         let mut err = struct_span_err!(tcx.sess, impl_item.span, E0201,
                                                        "duplicate definitions with name `{}`:",
                                                        impl_item.name);
-                        span_note!(&mut err, *entry.get(),
-                                   "previous definition of `{}` here",
-                                   impl_item.name);
+                        err.span_label(*entry.get(),
+                                   &format!("previous definition of `{}` here",
+                                        impl_item.name));
+                        err.span_label(impl_item.span, &format!("duplicate definition"));
                         err.emit();
                     }
                     Vacant(entry) => {
@@ -1013,11 +1017,12 @@ fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         let fid = ccx.tcx.map.local_def_id(f.id);
         let dup_span = seen_fields.get(&f.name).cloned();
         if let Some(prev_span) = dup_span {
-            let mut err = struct_span_err!(ccx.tcx.sess, f.span, E0124,
-                                           "field `{}` is already declared",
-                                           f.name);
-            span_note!(&mut err, prev_span, "previously declared here");
-            err.emit();
+            struct_span_err!(ccx.tcx.sess, f.span, E0124,
+                             "field `{}` is already declared",
+                             f.name)
+                .span_label(f.span, &"field already declared")
+                .span_label(prev_span, &format!("`{}` first declared here", f.name))
+                .emit();
         } else {
             seen_fields.insert(f.name, f.span);
         }
@@ -1060,6 +1065,7 @@ fn evaluate_disr_expr(ccx: &CrateCtxt, repr_ty: attr::IntType, e: &hir::Expr)
         let print_err = |cv: ConstVal| {
             struct_span_err!(ccx.tcx.sess, e.span, E0079, "mismatched types")
                 .note_expected_found(&"type", &ty_hint, &format!("{}", cv.description()))
+                .span_label(e.span, &format!("expected '{}' type", ty_hint))
                 .emit();
         };
 
@@ -2146,14 +2152,6 @@ fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
     abi: abi::Abi)
     -> ty::TypeScheme<'tcx>
 {
-    for i in &decl.inputs {
-        match i.pat.node {
-            PatKind::Binding(..) | PatKind::Wild => {}
-            _ => span_err!(ccx.tcx.sess, i.pat.span, E0130,
-                           "patterns aren't allowed in foreign function declarations")
-        }
-    }
-
     let ty_generics = ty_generics_for_fn(ccx, ast_generics, &ty::Generics::empty());
 
     let rb = BindingRscope::new();
@@ -2327,8 +2325,12 @@ fn report_unused_parameter(ccx: &CrateCtxt,
                            kind: &str,
                            name: &str)
 {
-    span_err!(ccx.tcx.sess, span, E0207,
-              "the {} parameter `{}` is not constrained by the \
-               impl trait, self type, or predicates",
-              kind, name);
+    struct_span_err!(
+        ccx.tcx.sess, span, E0207,
+        "the {} parameter `{}` is not constrained by the \
+        impl trait, self type, or predicates",
+        kind, name)
+        .span_label(span, &format!("unconstrained lifetime parameter"))
+        .emit();
+
 }
index cd2259a283469279df6ddd8286434ff76ef2ffa2..64b27857d2c610b50e6cc04850585b46ba4275ca 100644 (file)
@@ -1800,39 +1800,6 @@ struct Foo<U=(), T=U> {
 parameter if so.
 "##,
 
-E0130: r##"
-You declared a pattern as an argument in a foreign function declaration.
-Erroneous code example:
-
-```compile_fail
-extern {
-    fn foo((a, b): (u32, u32)); // error: patterns aren't allowed in foreign
-                                //        function declarations
-}
-```
-
-Please replace the pattern argument with a regular one. Example:
-
-```
-struct SomeStruct {
-    a: u32,
-    b: u32,
-}
-
-extern {
-    fn foo(s: SomeStruct); // ok!
-}
-```
-
-Or:
-
-```
-extern {
-    fn foo(a: (u32, u32)); // ok!
-}
-```
-"##,
-
 E0131: r##"
 It is not possible to define `main` with type parameters, or even with function
 parameters. When `main` is present, it must take no arguments and return `()`.
@@ -3897,6 +3864,104 @@ fn fly(&self) {} // And now that's ok!
 ```
 "##,
 
+E0527: r##"
+The number of elements in an array or slice pattern differed from the number of
+elements in the array being matched.
+
+Example of erroneous code:
+
+```compile_fail,E0527
+#![feature(slice_patterns)]
+
+let r = &[1, 2, 3, 4];
+match r {
+    &[a, b] => { // error: pattern requires 2 elements but array
+                 //        has 4
+        println!("a={}, b={}", a, b);
+    }
+}
+```
+
+Ensure that the pattern is consistent with the size of the matched
+array. Additional elements can be matched with `..`:
+
+```
+#![feature(slice_patterns)]
+
+let r = &[1, 2, 3, 4];
+match r {
+    &[a, b, ..] => { // ok!
+        println!("a={}, b={}", a, b);
+    }
+}
+```
+"##,
+
+E0528: r##"
+An array or slice pattern required more elements than were present in the
+matched array.
+
+Example of erroneous code:
+
+```compile_fail,E0528
+#![feature(slice_patterns)]
+
+let r = &[1, 2];
+match r {
+    &[a, b, c, rest..] => { // error: pattern requires at least 3
+                            //        elements but array has 2
+        println!("a={}, b={}, c={} rest={:?}", a, b, c, rest);
+    }
+}
+```
+
+Ensure that the matched array has at least as many elements as the pattern
+requires. You can match an arbitrary number of remaining elements with `..`:
+
+```
+#![feature(slice_patterns)]
+
+let r = &[1, 2, 3, 4, 5];
+match r {
+    &[a, b, c, rest..] => { // ok!
+        // prints `a=1, b=2, c=3 rest=[4, 5]`
+        println!("a={}, b={}, c={} rest={:?}", a, b, c, rest);
+    }
+}
+```
+"##,
+
+E0529: r##"
+An array or slice pattern was matched against some other type.
+
+Example of erroneous code:
+
+```compile_fail,E0529
+#![feature(slice_patterns)]
+
+let r: f32 = 1.0;
+match r {
+    [a, b] => { // error: expected an array or slice, found `f32`
+        println!("a={}, b={}", a, b);
+    }
+}
+```
+
+Ensure that the pattern and the expression being matched on are of consistent
+types:
+
+```
+#![feature(slice_patterns)]
+
+let r = [1.0, 2.0];
+match r {
+    [a, b] => { // ok!
+        println!("a={}, b={}", a, b);
+    }
+}
+```
+"##,
+
 E0559: r##"
 An unknown field was specified into an enum's structure variant.
 
@@ -4018,8 +4083,5 @@ struct Simba {
     E0436, // functional record update requires a struct
     E0513, // no type for local variable ..
     E0521, // redundant default implementations of trait
-    E0527, // expected {} elements, found {}
-    E0528, // expected at least {} elements, found {}
-    E0529, // slice pattern expects array or slice, not `{}`
     E0533, // `{}` does not name a unit variant, unit struct or a constant
 }
index 3b2d02dc861c4c62c0b8542f0b3f0da67eddbef8..65e00705121a7e6dcc5745d3034f10d5c0550053 100644 (file)
@@ -211,11 +211,15 @@ fn check_main_fn_ty(ccx: &CrateCtxt,
             match tcx.map.find(main_id) {
                 Some(hir_map::NodeItem(it)) => {
                     match it.node {
-                        hir::ItemFn(_, _, _, _, ref ps, _)
-                        if ps.is_parameterized() => {
-                            span_err!(ccx.tcx.sess, main_span, E0131,
-                                      "main function is not allowed to have type parameters");
-                            return;
+                        hir::ItemFn(_, _, _, _, ref generics, _) => {
+                            if let Some(gen_span) = generics.span() {
+                                struct_span_err!(ccx.tcx.sess, gen_span, E0131,
+                                         "main function is not allowed to have type parameters")
+                                    .span_label(gen_span,
+                                                &format!("main cannot have type parameters"))
+                                    .emit();
+                                return;
+                            }
                         }
                         _ => ()
                     }
@@ -261,8 +265,11 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
                     match it.node {
                         hir::ItemFn(_,_,_,_,ref ps,_)
                         if ps.is_parameterized() => {
-                            span_err!(tcx.sess, start_span, E0132,
-                                      "start function is not allowed to have type parameters");
+                            struct_span_err!(tcx.sess, start_span, E0132,
+                                "start function is not allowed to have type parameters")
+                                .span_label(ps.span().unwrap(),
+                                            &format!("start function cannot have type parameters"))
+                                .emit();
                             return;
                         }
                         _ => ()
index 1459420cdc00ce0b4f446ee5169ba36808f27070..914599271aca279044667c6ff0cb572d0a7d2ce2 100644 (file)
@@ -49,6 +49,7 @@
 
 use any::TypeId;
 use boxed::Box;
+use cell;
 use char;
 use fmt::{self, Debug, Display};
 use marker::{Send, Sync, Reflect};
@@ -289,6 +290,20 @@ fn description(&self) -> &str {
     }
 }
 
+#[unstable(feature = "try_borrow", issue = "35070")]
+impl<'a, T: ?Sized + Reflect> Error for cell::BorrowError<'a, T> {
+    fn description(&self) -> &str {
+        "already mutably borrowed"
+    }
+}
+
+#[unstable(feature = "try_borrow", issue = "35070")]
+impl<'a, T: ?Sized + Reflect> Error for cell::BorrowMutError<'a, T> {
+    fn description(&self) -> &str {
+        "already borrowed"
+    }
+}
+
 // copied from any.rs
 impl Error + 'static {
     /// Returns true if the boxed type is the same as `T`
index 0d3e18f9b966a2848781cafd10f2944d14ec2156..e0501f9cc61d24c70781bab1cf2645d2ed143ffe 100644 (file)
@@ -356,11 +356,32 @@ fn borrow(&self) -> &CStr { self }
 impl NulError {
     /// Returns the position of the nul byte in the slice that was provided to
     /// `CString::new`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ffi::CString;
+    ///
+    /// let nul_error = CString::new("foo\0bar").unwrap_err();
+    /// assert_eq!(nul_error.nul_position(), 3);
+    ///
+    /// let nul_error = CString::new("foo bar\0").unwrap_err();
+    /// assert_eq!(nul_error.nul_position(), 7);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn nul_position(&self) -> usize { self.0 }
 
     /// Consumes this error, returning the underlying vector of bytes which
     /// generated the error in the first place.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ffi::CString;
+    ///
+    /// let nul_error = CString::new("foo\0bar").unwrap_err();
+    /// assert_eq!(nul_error.into_vec(), b"foo\0bar");
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_vec(self) -> Vec<u8> { self.1 }
 }
index 38fd93501a528520f7b1ea951780f5209b966dba..b78db24e44b70784d202a6cff358804e88bda909 100644 (file)
@@ -156,7 +156,10 @@ pub struct File {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Permissions(fs_imp::FilePermissions);
 
-/// An structure representing a type of file with accessors for each file type.
+/// A structure representing a type of file with accessors for each file type.
+/// It is returned by [`Metadata::file_type`] method.
+///
+/// [`Metadata::file_type`]: struct.Metadata.html#method.file_type
 #[stable(feature = "file_type", since = "1.1.0")]
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct FileType(fs_imp::FileType);
@@ -610,6 +613,19 @@ fn as_inner_mut(&mut self) -> &mut fs_imp::OpenOptions { &mut self.0 }
 
 impl Metadata {
     /// Returns the file type for this metadata.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # fn foo() -> std::io::Result<()> {
+    /// use std::fs;
+    ///
+    /// let metadata = try!(fs::metadata("foo.txt"));
+    ///
+    /// println!("{:?}", metadata.file_type());
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "file_type", since = "1.1.0")]
     pub fn file_type(&self) -> FileType {
         FileType(self.0.file_type())
@@ -839,14 +855,56 @@ pub fn set_readonly(&mut self, readonly: bool) {
 
 impl FileType {
     /// Test whether this file type represents a directory.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # fn foo() -> std::io::Result<()> {
+    /// use std::fs;
+    ///
+    /// let metadata = try!(fs::metadata("foo.txt"));
+    /// let file_type = metadata.file_type();
+    ///
+    /// assert_eq!(file_type.is_dir(), false);
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "file_type", since = "1.1.0")]
     pub fn is_dir(&self) -> bool { self.0.is_dir() }
 
     /// Test whether this file type represents a regular file.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # fn foo() -> std::io::Result<()> {
+    /// use std::fs;
+    ///
+    /// let metadata = try!(fs::metadata("foo.txt"));
+    /// let file_type = metadata.file_type();
+    ///
+    /// assert_eq!(file_type.is_file(), true);
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "file_type", since = "1.1.0")]
     pub fn is_file(&self) -> bool { self.0.is_file() }
 
     /// Test whether this file type represents a symbolic link.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # fn foo() -> std::io::Result<()> {
+    /// use std::fs;
+    ///
+    /// let metadata = try!(fs::metadata("foo.txt"));
+    /// let file_type = metadata.file_type();
+    ///
+    /// assert_eq!(file_type.is_symlink(), false);
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "file_type", since = "1.1.0")]
     pub fn is_symlink(&self) -> bool { self.0.is_symlink() }
 }
index 05ae8ed5b0b66be71b491821fa99be19f2534f74..5333b0a531eaebd671245e8081c71a4cb72cc028 100644 (file)
@@ -55,7 +55,9 @@
 ///
 /// Errors mostly originate from the underlying OS, but custom instances of
 /// `Error` can be created with crafted error messages and a particular value of
-/// `ErrorKind`.
+/// [`ErrorKind`].
+///
+/// [`ErrorKind`]: enum.ErrorKind.html
 #[derive(Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Error {
@@ -77,6 +79,10 @@ struct Custom {
 ///
 /// This list is intended to grow over time and it is not recommended to
 /// exhaustively match against it.
+///
+/// It is used with the [`io::Error`] type.
+///
+/// [`io::Error`]: struct.Error.html
 #[derive(Copy, PartialEq, Eq, Clone, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow(deprecated)]
@@ -208,6 +214,14 @@ fn _new(kind: ErrorKind, error: Box<error::Error+Send+Sync>) -> Error {
     /// This function reads the value of `errno` for the target platform (e.g.
     /// `GetLastError` on Windows) and will return a corresponding instance of
     /// `Error` for the error code.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::Error;
+    ///
+    /// println!("last OS error: {:?}", Error::last_os_error());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn last_os_error() -> Error {
         Error::from_raw_os_error(sys::os::errno() as i32)
@@ -248,6 +262,27 @@ pub fn from_raw_os_error(code: i32) -> Error {
     /// If this `Error` was constructed via `last_os_error` or
     /// `from_raw_os_error`, then this function will return `Some`, otherwise
     /// it will return `None`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{Error, ErrorKind};
+    ///
+    /// fn print_os_error(err: &Error) {
+    ///     if let Some(raw_os_err) = err.raw_os_error() {
+    ///         println!("raw OS error: {:?}", raw_os_err);
+    ///     } else {
+    ///         println!("Not an OS error");
+    ///     }
+    /// }
+    ///
+    /// fn main() {
+    ///     // Will print "raw OS error: ...".
+    ///     print_os_error(&Error::last_os_error());
+    ///     // Will print "Not an OS error".
+    ///     print_os_error(&Error::new(ErrorKind::Other, "oh no!"));
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn raw_os_error(&self) -> Option<i32> {
         match self.repr {
@@ -260,6 +295,27 @@ pub fn raw_os_error(&self) -> Option<i32> {
     ///
     /// If this `Error` was constructed via `new` then this function will
     /// return `Some`, otherwise it will return `None`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{Error, ErrorKind};
+    ///
+    /// fn print_error(err: &Error) {
+    ///     if let Some(inner_err) = err.get_ref() {
+    ///         println!("Inner error: {:?}", inner_err);
+    ///     } else {
+    ///         println!("No inner error");
+    ///     }
+    /// }
+    ///
+    /// fn main() {
+    ///     // Will print "No inner error".
+    ///     print_error(&Error::last_os_error());
+    ///     // Will print "Inner error: ...".
+    ///     print_error(&Error::new(ErrorKind::Other, "oh no!"));
+    /// }
+    /// ```
     #[stable(feature = "io_error_inner", since = "1.3.0")]
     pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> {
         match self.repr {
@@ -273,6 +329,63 @@ pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> {
     ///
     /// If this `Error` was constructed via `new` then this function will
     /// return `Some`, otherwise it will return `None`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{Error, ErrorKind};
+    /// use std::{error, fmt};
+    /// use std::fmt::Display;
+    ///
+    /// #[derive(Debug)]
+    /// struct MyError {
+    ///     v: String,
+    /// }
+    ///
+    /// impl MyError {
+    ///     fn new() -> MyError {
+    ///         MyError {
+    ///             v: "oh no!".to_owned()
+    ///         }
+    ///     }
+    ///
+    ///     fn change_message(&mut self, new_message: &str) {
+    ///         self.v = new_message.to_owned();
+    ///     }
+    /// }
+    ///
+    /// impl error::Error for MyError {
+    ///     fn description(&self) -> &str { &self.v }
+    /// }
+    ///
+    /// impl Display for MyError {
+    ///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    ///         write!(f, "MyError: {}", &self.v)
+    ///     }
+    /// }
+    ///
+    /// fn change_error(mut err: Error) -> Error {
+    ///     if let Some(inner_err) = err.get_mut() {
+    ///         inner_err.downcast_mut::<MyError>().unwrap().change_message("I've been changed!");
+    ///     }
+    ///     err
+    /// }
+    ///
+    /// fn print_error(err: &Error) {
+    ///     if let Some(inner_err) = err.get_ref() {
+    ///         println!("Inner error: {}", inner_err);
+    ///     } else {
+    ///         println!("No inner error");
+    ///     }
+    /// }
+    ///
+    /// fn main() {
+    ///     // Will print "No inner error".
+    ///     print_error(&change_error(Error::last_os_error()));
+    ///     // Will print "Inner error: ...".
+    ///     print_error(&change_error(Error::new(ErrorKind::Other, MyError::new())));
+    /// }
+    /// ```
     #[stable(feature = "io_error_inner", since = "1.3.0")]
     pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> {
         match self.repr {
@@ -285,6 +398,27 @@ pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> {
     ///
     /// If this `Error` was constructed via `new` then this function will
     /// return `Some`, otherwise it will return `None`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{Error, ErrorKind};
+    ///
+    /// fn print_error(err: Error) {
+    ///     if let Some(inner_err) = err.into_inner() {
+    ///         println!("Inner error: {}", inner_err);
+    ///     } else {
+    ///         println!("No inner error");
+    ///     }
+    /// }
+    ///
+    /// fn main() {
+    ///     // Will print "No inner error".
+    ///     print_error(Error::last_os_error());
+    ///     // Will print "Inner error: ...".
+    ///     print_error(Error::new(ErrorKind::Other, "oh no!"));
+    /// }
+    /// ```
     #[stable(feature = "io_error_inner", since = "1.3.0")]
     pub fn into_inner(self) -> Option<Box<error::Error+Send+Sync>> {
         match self.repr {
@@ -294,6 +428,23 @@ pub fn into_inner(self) -> Option<Box<error::Error+Send+Sync>> {
     }
 
     /// Returns the corresponding `ErrorKind` for this error.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{Error, ErrorKind};
+    ///
+    /// fn print_error(err: Error) {
+    ///     println!("{:?}", err.kind());
+    /// }
+    ///
+    /// fn main() {
+    ///     // Will print "No inner error".
+    ///     print_error(Error::last_os_error());
+    ///     // Will print "Inner error: ...".
+    ///     print_error(Error::new(ErrorKind::AddrInUse, "oh no!"));
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn kind(&self) -> ErrorKind {
         match self.repr {
index d5b255ee57376fb9dac3495ad74a9d453477f9ce..88fd4186e0a2a73be02e98964f822de8c46c692d 100644 (file)
@@ -1082,16 +1082,22 @@ pub trait Seek {
     ///
     /// If the seek operation completed successfully,
     /// this method returns the new position from the start of the stream.
-    /// That position can be used later with `SeekFrom::Start`.
+    /// That position can be used later with [`SeekFrom::Start`].
     ///
     /// # Errors
     ///
     /// Seeking to a negative offset is considered an error.
+    ///
+    /// [`SeekFrom::Start`]: enum.SeekFrom.html#variant.Start
     #[stable(feature = "rust1", since = "1.0.0")]
     fn seek(&mut self, pos: SeekFrom) -> Result<u64>;
 }
 
 /// Enumeration of possible methods to seek within an I/O object.
+///
+/// It is used by the [`Seek`] trait.
+///
+/// [`Seek`]: trait.Seek.html
 #[derive(Copy, PartialEq, Eq, Clone, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum SeekFrom {
@@ -1482,6 +1488,24 @@ impl<T> Take<T> {
     ///
     /// This instance may reach EOF after reading fewer bytes than indicated by
     /// this method if the underlying `Read` instance reaches EOF.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io;
+    /// use std::io::prelude::*;
+    /// use std::fs::File;
+    ///
+    /// # fn foo() -> io::Result<()> {
+    /// let f = try!(File::open("foo.txt"));
+    ///
+    /// // read at most five bytes
+    /// let handle = f.take(5);
+    ///
+    /// println!("limit: {}", handle.limit());
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn limit(&self) -> u64 { self.limit }
 }
index c4b573db5f2dd41b44f4179cba30e5680ed88cfe..b8b66a58359e7013d135713767a4936c1a3d8c0d 100644 (file)
@@ -240,6 +240,21 @@ impl Stdin {
     ///
     /// [`Read`]: trait.Read.html
     /// [`BufRead`]: trait.BufRead.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{self, Read};
+    ///
+    /// # fn foo() -> io::Result<String> {
+    /// let mut buffer = String::new();
+    /// let stdin = io::stdin();
+    /// let mut handle = stdin.lock();
+    ///
+    /// try!(handle.read_to_string(&mut buffer));
+    /// # Ok(buffer)
+    /// # }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StdinLock {
         StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
@@ -399,6 +414,21 @@ impl Stdout {
     ///
     /// The lock is released when the returned lock goes out of scope. The
     /// returned guard also implements the `Write` trait for writing data.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{self, Write};
+    ///
+    /// # fn foo() -> io::Result<()> {
+    /// let stdout = io::stdout();
+    /// let mut handle = stdout.lock();
+    ///
+    /// try!(handle.write(b"hello world"));
+    ///
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StdoutLock {
         StdoutLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
@@ -505,6 +535,21 @@ impl Stderr {
     ///
     /// The lock is released when the returned lock goes out of scope. The
     /// returned guard also implements the `Write` trait for writing data.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{self, Write};
+    ///
+    /// fn foo() -> io::Result<()> {
+    ///     let stderr = io::stderr();
+    ///     let mut handle = stderr.lock();
+    ///
+    ///     try!(handle.write(b"hello world"));
+    ///
+    ///     Ok(())
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StderrLock {
         StderrLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
index 865d067cdb6dced4522f9873b87575ecfbb4aa0f..c6272012d66d5b13bb1010658e0c9b220b3bf85d 100644 (file)
 #![feature(str_utf16)]
 #![feature(test, rustc_private)]
 #![feature(thread_local)]
+#![feature(try_borrow)]
 #![feature(try_from)]
 #![feature(unboxed_closures)]
 #![feature(unicode)]
index ac13b23ebee50256b70f780917b182f77ffce26b..11a16b271133be76cbc9ca1c386588a43b091ae6 100644 (file)
 mod parser;
 #[cfg(test)] mod test;
 
-/// Possible values which can be passed to the `shutdown` method of `TcpStream`.
+/// Possible values which can be passed to the [`shutdown`] method of
+/// [`TcpStream`].
+///
+/// [`shutdown`]: struct.TcpStream.html#method.shutdown
+/// [`TcpStream`]: struct.TcpStream.html
 #[derive(Copy, Clone, PartialEq, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Shutdown {
index 5ab0d5a0877b7fee92d85e95b0c3806e3ab0a0bc..76617f159707dd2233da5ce8ab72b247bf05b84e 100644 (file)
 ///
 /// This iterator will infinitely yield `Some` of the accepted connections. It
 /// is equivalent to calling `accept` in a loop.
+///
+/// This `struct` is created by the [`incoming`] method on [`TcpListener`].
+///
+/// [`incoming`]: struct.TcpListener.html#method.incoming
+/// [`TcpListener`]: struct.TcpListener.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Incoming<'a> { listener: &'a TcpListener }
 
index c0e6ec46b55b9537d4a152fc6318bca224730f34..c1b4f8a8c88c501d9dc174c8f7186001a9f37b15 100644 (file)
@@ -408,7 +408,7 @@ fn write_str_escaped(f: &mut fmt::Formatter, s: &str) -> fmt::Result {
                             &self.bytes[pos .. surrogate_pos]
                         )},
                     )?;
-                    write!(formatter, "\\u{{{:X}}}", surrogate)?;
+                    write!(formatter, "\\u{{{:x}}}", surrogate)?;
                     pos = surrogate_pos + 3;
                 }
             }
@@ -1066,7 +1066,7 @@ fn c(value: &u32) -> CodePoint { CodePoint::from_u32(*value).unwrap() }
     fn wtf8buf_show() {
         let mut string = Wtf8Buf::from_str("a\té \u{7f}💩\r");
         string.push(CodePoint::from_u32(0xD800).unwrap());
-        assert_eq!(format!("{:?}", string), "\"a\\té \\u{7f}\u{1f4a9}\\r\\u{D800}\"");
+        assert_eq!(format!("{:?}", string), "\"a\\té \\u{7f}\u{1f4a9}\\r\\u{d800}\"");
     }
 
     #[test]
index b315e6762633b3fd982566c5a311360a3ad4065b..3b132744f7055ce176e0f0689aca601b53a454c6 100644 (file)
@@ -27,7 +27,7 @@
 #[cfg(any(target_os = "linux", target_os = "emscripten"))]
 use libc::{stat64, fstat64, lstat64, off64_t, ftruncate64, lseek64, dirent64, readdir64_r, open64};
 #[cfg(target_os = "android")]
-use libc::{stat as stat64, fstat as fstat64, lstat as lstat64, off64_t, lseek64,
+use libc::{stat as stat64, fstat as fstat64, lstat as lstat64, lseek64,
            dirent as dirent64, open as open64};
 #[cfg(not(any(target_os = "linux",
               target_os = "emscripten",
@@ -485,9 +485,11 @@ pub fn flush(&self) -> io::Result<()> { Ok(()) }
 
     pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
         let (whence, pos) = match pos {
-            SeekFrom::Start(off) => (libc::SEEK_SET, off as off64_t),
-            SeekFrom::End(off) => (libc::SEEK_END, off as off64_t),
-            SeekFrom::Current(off) => (libc::SEEK_CUR, off as off64_t),
+            // Casting to `i64` is fine, too large values will end up as
+            // negative which will cause an error in `lseek64`.
+            SeekFrom::Start(off) => (libc::SEEK_SET, off as i64),
+            SeekFrom::End(off) => (libc::SEEK_END, off),
+            SeekFrom::Current(off) => (libc::SEEK_CUR, off),
         };
         let n = cvt(unsafe { lseek64(self.0.raw(), pos, whence) })?;
         Ok(n as u64)
index 4c3558f91f5f22e65cf3c3892f45af47576e9a60..9c57f25dfcce8eb65585d51fa42d06459f114f94 100644 (file)
@@ -21,6 +21,7 @@
 use io;
 use iter;
 use libc::{self, c_int, c_char, c_void};
+use marker::PhantomData;
 use mem;
 use memchr;
 use path::{self, PathBuf};
@@ -37,6 +38,7 @@
 
 
 extern {
+    #[cfg(not(target_os = "dragonfly"))]
     #[cfg_attr(any(target_os = "linux", target_os = "emscripten"),
                link_name = "__errno_location")]
     #[cfg_attr(any(target_os = "bitrig",
@@ -304,7 +306,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
 
 pub struct Args {
     iter: vec::IntoIter<OsString>,
-    _dont_send_or_sync_me: *mut (),
+    _dont_send_or_sync_me: PhantomData<*mut ()>,
 }
 
 impl Iterator for Args {
@@ -342,7 +344,7 @@ pub fn args() -> Args {
     };
     Args {
         iter: vec.into_iter(),
-        _dont_send_or_sync_me: ptr::null_mut(),
+        _dont_send_or_sync_me: PhantomData,
     }
 }
 
@@ -399,7 +401,7 @@ pub fn args() -> Args {
         }
     }
 
-    Args { iter: res.into_iter(), _dont_send_or_sync_me: ptr::null_mut() }
+    Args { iter: res.into_iter(), _dont_send_or_sync_me: PhantomData }
 }
 
 #[cfg(any(target_os = "linux",
@@ -418,12 +420,12 @@ pub fn args() -> Args {
     let v: Vec<OsString> = bytes.into_iter().map(|v| {
         OsStringExt::from_vec(v)
     }).collect();
-    Args { iter: v.into_iter(), _dont_send_or_sync_me: ptr::null_mut() }
+    Args { iter: v.into_iter(), _dont_send_or_sync_me: PhantomData }
 }
 
 pub struct Env {
     iter: vec::IntoIter<(OsString, OsString)>,
-    _dont_send_or_sync_me: *mut (),
+    _dont_send_or_sync_me: PhantomData<*mut ()>,
 }
 
 impl Iterator for Env {
@@ -464,7 +466,7 @@ pub fn env() -> Env {
         }
         let ret = Env {
             iter: result.into_iter(),
-            _dont_send_or_sync_me: ptr::null_mut(),
+            _dont_send_or_sync_me: PhantomData,
         };
         ENV_LOCK.unlock();
         return ret
index fbd4e1d120817ebc21a0b5e4e08d2f8593ff02d2..08aeb5fb8ccdeae96abf30a8569e9824dfc34856 100644 (file)
@@ -50,7 +50,9 @@ pub unsafe fn read(&self) {
         // the implementation allows recursive locking. The POSIX standard
         // doesn't require recursivly locking a rwlock to deadlock, but we can't
         // allow that because it could lead to aliasing issues.
-        if r == libc::EDEADLK || *self.write_locked.get() {
+        if r == libc::EAGAIN {
+            panic!("rwlock maximum reader count exceeded");
+        } else if r == libc::EDEADLK || *self.write_locked.get() {
             if r == 0 {
                 self.raw_unlock();
             }
index 2683e57256dc79afc29a2872a31861f77a788d53..4e6cef9a28d8f32147d5db051c5e95c2f5469a69 100644 (file)
@@ -324,6 +324,8 @@ pub fn flush(&self) -> io::Result<()> { Ok(()) }
 
     pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
         let (whence, pos) = match pos {
+            // Casting to `i64` is fine, `SetFilePointerEx` reinterprets this
+            // integer as `u64`.
             SeekFrom::Start(n) => (c::FILE_BEGIN, n as i64),
             SeekFrom::End(n) => (c::FILE_END, n),
             SeekFrom::Current(n) => (c::FILE_CURRENT, n),
index e9736fea7b37f43955f04d7137cefa517cfaaa9b..f06c105d30e6500eee11e92e8f8c73ecdd4c07ff 100644 (file)
@@ -447,6 +447,8 @@ pub fn park() {
     *guard = false;
 }
 
+/// Use [park_timeout].
+///
 /// Blocks unless or until the current thread's token is made available or
 /// the specified duration has been reached (may wake spuriously).
 ///
@@ -456,7 +458,10 @@ pub fn park() {
 /// preemption or platform differences that may not cause the maximum
 /// amount of time waited to be precisely `ms` long.
 ///
-/// See the module doc for more detail.
+/// See the [module documentation][thread] for more detail.
+///
+/// [thread]: index.html
+/// [park_timeout]: fn.park_timeout.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::thread::park_timeout`")]
 pub fn park_timeout_ms(ms: u32) {
@@ -478,6 +483,25 @@ pub fn park_timeout_ms(ms: u32) {
 ///
 /// Platforms which do not support nanosecond precision for sleeping will have
 /// `dur` rounded up to the nearest granularity of time they can sleep for.
+///
+/// # Example
+///
+/// Waiting for the complete expiration of the timeout:
+///
+/// ```rust,no_run
+/// use std::thread::park_timeout;
+/// use std::time::{Instant, Duration};
+///
+/// let timeout = Duration::from_secs(2);
+/// let beginning_park = Instant::now();
+/// park_timeout(timeout);
+///
+/// while beginning_park.elapsed() < timeout {
+///     println!("restarting park_timeout after {:?}", beginning_park.elapsed());
+///     let timeout = timeout - beginning_park.elapsed();
+///     park_timeout(timeout);
+/// }
+/// ```
 #[stable(feature = "park_timeout", since = "1.4.0")]
 pub fn park_timeout(dur: Duration) {
     let thread = current();
index a8aca90e6238daf18f6503aa6f7b7664dd35366e..b176b8fefc612c718639bbc1ada2fe8ef0ab88a1 100644 (file)
@@ -71,6 +71,23 @@ pub fn dummy_spanned<T>(t: T) -> Spanned<T> {
     respan(DUMMY_SP, t)
 }
 
+/// Build a span that covers the two provided spans.
+pub fn combine_spans(sp1: Span, sp2: Span) -> Span {
+    if sp1 == DUMMY_SP && sp2 == DUMMY_SP {
+        DUMMY_SP
+    } else if sp1 == DUMMY_SP {
+        sp2
+    } else if sp2 == DUMMY_SP {
+        sp1
+    } else {
+        Span {
+            lo: if sp1.lo < sp2.lo { sp1.lo } else { sp2.lo },
+            hi: if sp1.hi > sp2.hi { sp1.hi } else { sp2.hi },
+            expn_id: if sp1.expn_id == sp2.expn_id { sp1.expn_id } else { NO_EXPANSION },
+        }
+    }
+}
+
 #[derive(Clone, Hash, Debug)]
 pub struct NameAndSpan {
     /// The format with which the macro was invoked.
index 2147e8ec2eb1f4054ecef0715b4f0ab571786e6f..7b28952aff6b6576b740ab809ed75fd1a15e77a6 100644 (file)
@@ -237,7 +237,7 @@ pub fn new_parser_from_ts<'a>(sess: &'a ParseSess,
                               cfg: ast::CrateConfig,
                               ts: tokenstream::TokenStream)
                               -> Parser<'a> {
-    tts_to_parser(sess, ts.tts, cfg)
+    tts_to_parser(sess, ts.to_tts(), cfg)
 }
 
 
index d38edf816880e1e44d9aa81ab93a4ba20b427257..89ead21cc10cb2fda48f0f88258cee98e759244a 100644 (file)
 //! or a SequenceRepetition specifier (for the purpose of sequence generation during macro
 //! expansion).
 //!
-//! A TokenStream also has a slice view, `TokenSlice`, that is analogous to `str` for
-//! `String`: it allows the programmer to divvy up, explore, and otherwise partition a
-//! TokenStream as borrowed subsequences.
+//! ## Ownership
+//! TokenStreams are persistant data structures construced as ropes with reference
+//! counted-children. In general, this means that calling an operation on a TokenStream
+//! (such as `slice`) produces an entirely new TokenStream from the borrowed reference to
+//! the original. This essentially coerces TokenStreams into 'views' of their subparts,
+//! and a borrowed TokenStream is sufficient to build an owned TokenStream without taking
+//! ownership of the original.
 
 use ast::{self, AttrStyle, LitKind};
 use syntax_pos::{Span, DUMMY_SP, NO_EXPANSION};
-use codemap::Spanned;
+use codemap::{Spanned, combine_spans};
 use ext::base;
 use ext::tt::macro_parser;
 use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
 use parse::lexer;
 use parse;
-use parse::token::{self, Token, Lit, InternedString, Nonterminal};
-use parse::token::Lit as TokLit;
+use parse::token::{self, Token, Lit, Nonterminal};
 
 use std::fmt;
-use std::mem;
-use std::ops::Index;
-use std::ops;
 use std::iter::*;
-
+use std::ops::{self, Index};
 use std::rc::Rc;
 
 /// A delimited sequence of token trees
@@ -335,27 +335,51 @@ pub fn maybe_str(&self) -> Option<ast::Lit> {
 /// struct itself shouldn't be directly manipulated; the internal structure is not stable,
 /// and may be changed at any time in the future. The operators will not, however (except
 /// for signatures, later on).
-#[derive(Eq,Clone,Hash,RustcEncodable,RustcDecodable)]
+#[derive(Clone, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub struct TokenStream {
-    pub span: Span,
-    pub tts: Vec<TokenTree>,
+    ts: InternalTS,
+}
+
+// NB If Leaf access proves to be slow, inroducing a secondary Leaf without the bounds
+// for unsliced Leafs may lead to some performance improvemenet.
+#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+pub enum InternalTS {
+    Empty(Span),
+    Leaf {
+        tts: Rc<Vec<TokenTree>>,
+        offset: usize,
+        len: usize,
+        sp: Span,
+    },
+    Node {
+        left: Rc<InternalTS>,
+        right: Rc<InternalTS>,
+        len: usize,
+        sp: Span,
+    },
 }
 
 impl fmt::Debug for TokenStream {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        if self.tts.len() == 0 {
-            write!(f, "([empty")?;
-        } else {
-            write!(f, "([")?;
-            write!(f, "{:?}", self.tts[0])?;
-
-            for tt in self.tts.iter().skip(1) {
-                write!(f, ",{:?}", tt)?;
+        self.ts.fmt(f)
+    }
+}
+
+impl fmt::Debug for InternalTS {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            InternalTS::Empty(..) => Ok(()),
+            InternalTS::Leaf { ref tts, offset, len, .. } => {
+                for t in tts.iter().skip(offset).take(len) {
+                    try!(write!(f, "{:?}", t));
+                }
+                Ok(())
+            }
+            InternalTS::Node { ref left, ref right, .. } => {
+                try!(left.fmt(f));
+                right.fmt(f)
             }
         }
-        write!(f, "|")?;
-        self.span.fmt(f)?;
-        write!(f, "])")
     }
 }
 
@@ -363,7 +387,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// equality, see `eq_unspanned`.
 impl PartialEq<TokenStream> for TokenStream {
     fn eq(&self, other: &TokenStream) -> bool {
-        self.tts == other.tts
+        self.iter().eq(other.iter())
     }
 }
 
@@ -408,6 +432,59 @@ fn covering_span(trees: &[TokenTree]) -> Span {
     }
 }
 
+impl InternalTS {
+    fn len(&self) -> usize {
+        match *self {
+            InternalTS::Empty(..) => 0,
+            InternalTS::Leaf { len, .. } => len,
+            InternalTS::Node { len, .. } => len,
+        }
+    }
+
+    fn span(&self) -> Span {
+        match *self {
+            InternalTS::Empty(sp) |
+            InternalTS::Leaf { sp, .. } |
+            InternalTS::Node { sp, .. } => sp,
+        }
+    }
+
+    fn slice(&self, range: ops::Range<usize>) -> TokenStream {
+        let from = range.start;
+        let to = range.end;
+        if from == to {
+            return TokenStream::mk_empty();
+        }
+        if from > to {
+            panic!("Invalid range: {} to {}", from, to);
+        }
+        if from == 0 && to == self.len() {
+            return TokenStream { ts: self.clone() }; /* should be cheap */
+        }
+        match *self {
+            InternalTS::Empty(..) => panic!("Invalid index"),
+            InternalTS::Leaf { ref tts, offset, .. } => {
+                let offset = offset + from;
+                let len = to - from;
+                TokenStream::mk_sub_leaf(tts.clone(),
+                                         offset,
+                                         len,
+                                         covering_span(&tts[offset..offset + len]))
+            }
+            InternalTS::Node { ref left, ref right, .. } => {
+                let left_len = left.len();
+                if to <= left_len {
+                    left.slice(range)
+                } else if from >= left_len {
+                    right.slice(from - left_len..to - left_len)
+                } else {
+                    TokenStream::concat(left.slice(from..left_len), right.slice(0..to - left_len))
+                }
+            }
+        }
+    }
+}
+
 /// TokenStream operators include basic destructuring, boolean operations, `maybe_...`
 /// operations, and `maybe_..._prefix` operations. Boolean operations are straightforward,
 /// indicating information about the structure of the stream. The `maybe_...` operations
@@ -419,129 +496,149 @@ fn covering_span(trees: &[TokenTree]) -> Span {
 ///
 ///    `maybe_path_prefix("a::b::c(a,b,c).foo()") -> (a::b::c, "(a,b,c).foo()")`
 impl TokenStream {
-    /// Convert a vector of `TokenTree`s into a `TokenStream`.
-    pub fn from_tts(trees: Vec<TokenTree>) -> TokenStream {
-        let span = covering_span(&trees);
-        TokenStream {
-            tts: trees,
-            span: span,
-        }
+    pub fn mk_empty() -> TokenStream {
+        TokenStream { ts: InternalTS::Empty(DUMMY_SP) }
     }
 
-    /// Copies all of the TokenTrees from the TokenSlice, appending them to the stream.
-    pub fn append_stream(mut self, ts2: &TokenSlice) {
-        for tt in ts2.iter() {
-            self.tts.push(tt.clone());
-        }
-        self.span = covering_span(&self.tts[..]);
+    fn mk_spanned_empty(sp: Span) -> TokenStream {
+        TokenStream { ts: InternalTS::Empty(sp) }
     }
 
-    /// Manually change a TokenStream's span.
-    pub fn respan(self, span: Span) -> TokenStream {
+    fn mk_leaf(tts: Rc<Vec<TokenTree>>, sp: Span) -> TokenStream {
+        let len = tts.len();
         TokenStream {
-            tts: self.tts,
-            span: span,
+            ts: InternalTS::Leaf {
+                tts: tts,
+                offset: 0,
+                len: len,
+                sp: sp,
+            },
         }
     }
 
-    /// Construct a TokenStream from an ast literal.
-    pub fn from_ast_lit_str(lit: ast::Lit) -> Option<TokenStream> {
-        match lit.node {
-            LitKind::Str(val, _) => {
-                let val = TokLit::Str_(token::intern(&val));
-                Some(TokenStream::from_tts(vec![TokenTree::Token(lit.span,
-                                                                 Token::Literal(val, None))]))
-            }
-            _ => None,
+    fn mk_sub_leaf(tts: Rc<Vec<TokenTree>>, offset: usize, len: usize, sp: Span) -> TokenStream {
+        TokenStream {
+            ts: InternalTS::Leaf {
+                tts: tts,
+                offset: offset,
+                len: len,
+                sp: sp,
+            },
         }
-
     }
 
-    /// Convert a vector of TokenTrees into a parentheses-delimited TokenStream.
-    pub fn as_paren_delimited_stream(tts: Vec<TokenTree>) -> TokenStream {
-        let new_sp = covering_span(&tts);
-
-        let new_delim = Rc::new(Delimited {
-            delim: token::DelimToken::Paren,
-            open_span: DUMMY_SP,
-            tts: tts,
-            close_span: DUMMY_SP,
-        });
-
-        TokenStream::from_tts(vec![TokenTree::Delimited(new_sp, new_delim)])
+    fn mk_int_node(left: Rc<InternalTS>,
+                   right: Rc<InternalTS>,
+                   len: usize,
+                   sp: Span)
+                   -> TokenStream {
+        TokenStream {
+            ts: InternalTS::Node {
+                left: left,
+                right: right,
+                len: len,
+                sp: sp,
+            },
+        }
     }
 
-    /// Convert an interned string into a one-element TokenStream.
-    pub fn from_interned_string_as_ident(s: InternedString) -> TokenStream {
-        TokenStream::from_tts(vec![TokenTree::Token(DUMMY_SP,
-                                                    Token::Ident(token::str_to_ident(&s[..])))])
+    /// Convert a vector of `TokenTree`s into a `TokenStream`.
+    pub fn from_tts(trees: Vec<TokenTree>) -> TokenStream {
+        let span = covering_span(&trees[..]);
+        TokenStream::mk_leaf(Rc::new(trees), span)
     }
-}
-
-/// TokenSlices are 'views' of `TokenStream's; they fit the same role as `str`s do for
-/// `String`s. In general, most TokenStream manipulations will be refocusing their internal
-/// contents by taking a TokenSlice and then using indexing and the provided operators.
-#[derive(PartialEq, Eq, Debug)]
-pub struct TokenSlice([TokenTree]);
-
-impl ops::Deref for TokenStream {
-    type Target = TokenSlice;
 
-    fn deref(&self) -> &TokenSlice {
-        let tts: &[TokenTree] = &*self.tts;
-        unsafe { mem::transmute(tts) }
+    /// Manually change a TokenStream's span.
+    pub fn respan(self, span: Span) -> TokenStream {
+        match self.ts {
+            InternalTS::Empty(..) => TokenStream::mk_spanned_empty(span),
+            InternalTS::Leaf { tts, offset, len, .. } => {
+                TokenStream::mk_sub_leaf(tts, offset, len, span)
+            }
+            InternalTS::Node { left, right, len, .. } => {
+                TokenStream::mk_int_node(left, right, len, span)
+            }
+        }
     }
-}
 
-impl TokenSlice {
-    /// Convert a borrowed TokenTree slice into a borrowed TokenSlice.
-    fn from_tts(tts: &[TokenTree]) -> &TokenSlice {
-        unsafe { mem::transmute(tts) }
+    /// Concatenates two TokenStreams into a new TokenStream
+    pub fn concat(left: TokenStream, right: TokenStream) -> TokenStream {
+        let new_len = left.len() + right.len();
+        let new_span = combine_spans(left.span(), right.span());
+        TokenStream::mk_int_node(Rc::new(left.ts), Rc::new(right.ts), new_len, new_span)
     }
 
-    /// Indicates whether the `TokenStream` is empty.
+    /// Indicate if the TokenStream is empty.
     pub fn is_empty(&self) -> bool {
         self.len() == 0
     }
 
-    /// Return the `TokenSlice`'s length.
+    /// Return a TokenStream's length.
     pub fn len(&self) -> usize {
-        self.0.len()
+        self.ts.len()
     }
 
-    /// Check equality versus another TokenStream, ignoring span information.
-    pub fn eq_unspanned(&self, other: &TokenSlice) -> bool {
-        if self.len() != other.len() {
-            return false;
-        }
-        for (tt1, tt2) in self.iter().zip(other.iter()) {
-            if !tt1.eq_unspanned(tt2) {
-                return false;
+    /// Convert a TokenStream into a vector of borrowed TokenTrees.
+    pub fn to_vec(&self) -> Vec<&TokenTree> {
+        fn internal_to_vec(ts: &InternalTS) -> Vec<&TokenTree> {
+            match *ts {
+                InternalTS::Empty(..) => Vec::new(),
+                InternalTS::Leaf { ref tts, offset, len, .. } => {
+                    tts[offset..offset + len].iter().collect()
+                }
+                InternalTS::Node { ref left, ref right, .. } => {
+                    let mut v1 = internal_to_vec(left);
+                    let mut v2 = internal_to_vec(right);
+                    v1.append(&mut v2);
+                    v1
+                }
             }
         }
-        true
+        internal_to_vec(&self.ts)
     }
 
-    /// Compute a span that covers the entire TokenSlice (eg, one wide enough to include
-    /// the entire slice). If the inputs share expansion identification, it is preserved.
-    /// If they do not, it is discarded.
-    pub fn covering_span(&self) -> Span {
-        covering_span(&self.0)
+    /// Convert a TokenStream into a vector of TokenTrees (by cloning the TokenTrees).
+    /// (This operation is an O(n) deep copy of the underlying structure.)
+    pub fn to_tts(&self) -> Vec<TokenTree> {
+        self.to_vec().into_iter().cloned().collect::<Vec<TokenTree>>()
     }
 
-    /// Indicates where the stream is of the form `= <ts>`, where `<ts>` is a continued
-    /// `TokenStream`.
-    pub fn is_assignment(&self) -> bool {
-        self.maybe_assignment().is_some()
+    /// Return the TokenStream's span.
+    pub fn span(&self) -> Span {
+        self.ts.span()
     }
 
-    /// Returns the RHS of an assigment.
-    pub fn maybe_assignment(&self) -> Option<&TokenSlice> {
-        if !(self.len() > 1) {
-            return None;
+    /// Returns an iterator over a TokenStream (as a sequence of TokenTrees).
+    pub fn iter<'a>(&self) -> Iter {
+        Iter { vs: self, idx: 0 }
+    }
+
+    /// Splits a TokenStream based on the provided `&TokenTree -> bool` predicate.
+    pub fn split<P>(&self, pred: P) -> Split<P>
+        where P: FnMut(&TokenTree) -> bool
+    {
+        Split {
+            vs: self,
+            pred: pred,
+            finished: false,
+            idx: 0,
         }
+    }
+
+    /// Produce a slice of the input TokenStream from the `from` index, inclusive, to the
+    /// `to` index, non-inclusive.
+    pub fn slice(&self, range: ops::Range<usize>) -> TokenStream {
+        self.ts.slice(range)
+    }
+
+    /// Slice starting at the provided index, inclusive.
+    pub fn slice_from(&self, from: ops::RangeFrom<usize>) -> TokenStream {
+        self.slice(from.start..self.len())
+    }
 
-        Some(&self[1..])
+    /// Slice up to the provided index, non-inclusive.
+    pub fn slice_to(&self, to: ops::RangeTo<usize>) -> TokenStream {
+        self.slice(0..to.end)
     }
 
     /// Indicates where the stream is a single, delimited expression (e.g., `(a,b,c)` or
@@ -551,50 +648,15 @@ pub fn is_delimited(&self) -> bool {
     }
 
     /// Returns the inside of the delimited term as a new TokenStream.
-    pub fn maybe_delimited(&self) -> Option<&TokenSlice> {
+    pub fn maybe_delimited(&self) -> Option<TokenStream> {
         if !(self.len() == 1) {
             return None;
         }
 
+        // FIXME It would be nice to change Delimited to move the Rc around the TokenTree
+        // vector directly in order to avoid the clone here.
         match self[0] {
-            TokenTree::Delimited(_, ref rc) => Some(TokenSlice::from_tts(&*rc.tts)),
-            _ => None,
-        }
-    }
-
-    /// Returns a list of `TokenSlice`s if the stream is a delimited list, breaking the
-    /// stream on commas.
-    pub fn maybe_comma_list(&self) -> Option<Vec<&TokenSlice>> {
-        let maybe_tts = self.maybe_delimited();
-
-        let ts: &TokenSlice;
-        match maybe_tts {
-            Some(t) => {
-                ts = t;
-            }
-            None => {
-                return None;
-            }
-        }
-
-        let splits: Vec<&TokenSlice> = ts.split(|x| match *x {
-                TokenTree::Token(_, Token::Comma) => true,
-                _ => false,
-            })
-            .filter(|x| x.len() > 0)
-            .collect();
-
-        Some(splits)
-    }
-
-    /// Returns a Nonterminal if it is Interpolated.
-    pub fn maybe_interpolated_nonterminal(&self) -> Option<Nonterminal> {
-        if !(self.len() == 1) {
-            return None;
-        }
-
-        match self[0] {
-            TokenTree::Token(_, Token::Interpolated(ref nt)) => Some(nt.clone()),
+            TokenTree::Delimited(_, ref rc) => Some(TokenStream::from_tts(rc.tts.clone())),
             _ => None,
         }
     }
@@ -610,180 +672,54 @@ pub fn maybe_ident(&self) -> Option<ast::Ident> {
             return None;
         }
 
-        let tok = if let Some(tts) = self.maybe_delimited() {
-            if tts.len() != 1 {
-                return None;
-            }
-            &tts[0]
-        } else {
-            &self[0]
-        };
-
-        match *tok {
+        match self[0] {
             TokenTree::Token(_, Token::Ident(t)) => Some(t),
             _ => None,
         }
     }
 
-    /// Indicates if the stream is exactly one literal
-    pub fn is_lit(&self) -> bool {
-        self.maybe_lit().is_some()
-    }
-
-    /// Returns a literal
-    pub fn maybe_lit(&self) -> Option<token::Lit> {
-        if !(self.len() == 1) {
-            return None;
-        }
-
-        let tok = if let Some(tts) = self.maybe_delimited() {
-            if tts.len() != 1 {
-                return None;
-            }
-            &tts[0]
-        } else {
-            &self[0]
-        };
-
-        match *tok {
-            TokenTree::Token(_, Token::Literal(l, _)) => Some(l),
-            _ => None,
-        }
-    }
-
-    /// Returns an AST string literal if the TokenStream is either a normal ('cooked') or
-    /// raw string literal.
-    pub fn maybe_str(&self) -> Option<ast::Lit> {
-        if !(self.len() == 1) {
-            return None;
-        }
-
-        match self[0] {
-            TokenTree::Token(sp, Token::Literal(Lit::Str_(s), _)) => {
-                let l = LitKind::Str(token::intern_and_get_ident(&parse::str_lit(&s.as_str())),
-                                     ast::StrStyle::Cooked);
-                Some(Spanned {
-                    node: l,
-                    span: sp,
-                })
-            }
-            TokenTree::Token(sp, Token::Literal(Lit::StrRaw(s, n), _)) => {
-                let l = LitKind::Str(token::intern_and_get_ident(&parse::raw_str_lit(&s.as_str())),
-                                     ast::StrStyle::Raw(n));
-                Some(Spanned {
-                    node: l,
-                    span: sp,
-                })
+    /// Compares two TokenStreams, checking equality without regarding span information.
+    pub fn eq_unspanned(&self, other: &TokenStream) -> bool {
+        for (t1, t2) in self.iter().zip(other.iter()) {
+            if !t1.eq_unspanned(t2) {
+                return false;
             }
-            _ => None,
         }
+        true
     }
 
-    /// This operation extracts the path prefix , returning an AST path struct and the remainder
-    /// of the stream (if it finds one). To be more specific, a tokenstream that has a valid,
-    /// non-global path as a prefix (eg `foo(bar, baz)`, `foo::bar(bar)`, but *not*
-    /// `::foo::bar(baz)`) will yield the path and the remaining tokens (as a slice). The previous
-    /// examples will yield
-    /// `Some((Path { segments = vec![foo], ... }, [(bar, baz)]))`,
-    /// `Some((Path { segments = vec![foo, bar] }, [(baz)]))`,
-    /// and `None`, respectively.
-    pub fn maybe_path_prefix(&self) -> Option<(ast::Path, &TokenSlice)> {
-        let mut segments: Vec<ast::PathSegment> = Vec::new();
-
-        let path: Vec<&TokenTree> = self.iter()
-            .take_while(|x| x.is_ident() || x.eq_token(Token::ModSep))
-            .collect::<Vec<&TokenTree>>();
-
-        let path_size = path.len();
-        if path_size == 0 {
-            return None;
-        }
-
-        let cov_span = self[..path_size].covering_span();
-        let rst = &self[path_size..];
-
-        let fst_id = path[0];
-
-        if let Some(id) = fst_id.maybe_ident() {
-            segments.push(ast::PathSegment {
-                identifier: id,
-                parameters: ast::PathParameters::none(),
-            });
-        } else {
-            return None;
-        }
-
-        // Let's use a state machine to parse out the rest.
-        enum State {
-            Mod, // Expect a `::`, or return None otherwise.
-            Ident, // Expect an ident, or return None otherwise.
-        }
-        let mut state = State::Mod;
-
-        for p in &path[1..] {
-            match state {
-                State::Mod => {
-                    // State 0: ['::' -> state 1, else return None]
-                    if p.eq_token(Token::ModSep) {
-                        state = State::Ident;
-                    } else {
-                        return None;
-                    }
-                }
-                State::Ident => {
-                    // State 1: [ident -> state 0, else return None]
-                    if let Some(id) = p.maybe_ident() {
-                        segments.push(ast::PathSegment {
-                            identifier: id,
-                            parameters: ast::PathParameters::none(),
-                        });
-                        state = State::Mod;
-                    } else {
-                        return None;
-                    }
-                }
-            }
-        }
-
-        let path = ast::Path {
-            span: cov_span,
-            global: false,
-            segments: segments,
-        };
-        Some((path, rst))
-    }
+    /// Convert a vector of TokenTrees into a parentheses-delimited TokenStream.
+    pub fn as_delimited_stream(tts: Vec<TokenTree>, delim: token::DelimToken) -> TokenStream {
+        let new_sp = covering_span(&tts);
 
-    /// Returns an iterator over a TokenSlice (as a sequence of TokenStreams).
-    fn iter(&self) -> Iter {
-        Iter { vs: self }
-    }
+        let new_delim = Rc::new(Delimited {
+            delim: delim,
+            open_span: DUMMY_SP,
+            tts: tts,
+            close_span: DUMMY_SP,
+        });
 
-    /// Splits a TokenSlice based on the provided `&TokenTree -> bool` predicate.
-    fn split<P>(&self, pred: P) -> Split<P>
-        where P: FnMut(&TokenTree) -> bool
-    {
-        Split {
-            vs: self,
-            pred: pred,
-            finished: false,
-        }
+        TokenStream::from_tts(vec![TokenTree::Delimited(new_sp, new_delim)])
     }
 }
 
+// FIXME Reimplement this iterator to hold onto a slice iterator for a leaf, getting the
+// next leaf's iterator when the current one is exhausted.
 pub struct Iter<'a> {
-    vs: &'a TokenSlice,
+    vs: &'a TokenStream,
+    idx: usize,
 }
 
 impl<'a> Iterator for Iter<'a> {
     type Item = &'a TokenTree;
 
     fn next(&mut self) -> Option<&'a TokenTree> {
-        if self.vs.is_empty() {
+        if self.vs.is_empty() || self.idx >= self.vs.len() {
             return None;
         }
 
-        let ret = Some(&self.vs[0]);
-        self.vs = &self.vs[1..];
+        let ret = Some(&self.vs[self.idx]);
+        self.idx = self.idx + 1;
         ret
     }
 }
@@ -791,29 +727,35 @@ fn next(&mut self) -> Option<&'a TokenTree> {
 pub struct Split<'a, P>
     where P: FnMut(&TokenTree) -> bool
 {
-    vs: &'a TokenSlice,
+    vs: &'a TokenStream,
     pred: P,
     finished: bool,
+    idx: usize,
 }
 
 impl<'a, P> Iterator for Split<'a, P>
     where P: FnMut(&TokenTree) -> bool
 {
-    type Item = &'a TokenSlice;
+    type Item = TokenStream;
 
-    fn next(&mut self) -> Option<&'a TokenSlice> {
+    fn next(&mut self) -> Option<TokenStream> {
         if self.finished {
             return None;
         }
+        if self.idx >= self.vs.len() {
+            self.finished = true;
+            return None;
+        }
 
-        match self.vs.iter().position(|x| (self.pred)(x)) {
+        let mut lookup = self.vs.iter().skip(self.idx);
+        match lookup.position(|x| (self.pred)(&x)) {
             None => {
                 self.finished = true;
-                Some(&self.vs[..])
+                Some(self.vs.slice_from(self.idx..))
             }
-            Some(idx) => {
-                let ret = Some(&self.vs[..idx]);
-                self.vs = &self.vs[idx + 1..];
+            Some(edx) => {
+                let ret = Some(self.vs.slice(self.idx..self.idx + edx));
+                self.idx += edx + 1;
                 ret
             }
         }
@@ -824,98 +766,134 @@ impl Index<usize> for TokenStream {
     type Output = TokenTree;
 
     fn index(&self, index: usize) -> &TokenTree {
-        Index::index(&**self, index)
+        &self.ts[index]
     }
 }
 
-impl ops::Index<ops::Range<usize>> for TokenStream {
-    type Output = TokenSlice;
+impl Index<usize> for InternalTS {
+    type Output = TokenTree;
 
-    fn index(&self, index: ops::Range<usize>) -> &TokenSlice {
-        Index::index(&**self, index)
+    fn index(&self, index: usize) -> &TokenTree {
+        if self.len() <= index {
+            panic!("Index {} too large for {:?}", index, self);
+        }
+        match *self {
+            InternalTS::Empty(..) => panic!("Invalid index"),
+            InternalTS::Leaf { ref tts, offset, .. } => tts.get(index + offset).unwrap(),
+            InternalTS::Node { ref left, ref right, .. } => {
+                let left_len = left.len();
+                if index < left_len {
+                    Index::index(&**left, index)
+                } else {
+                    Index::index(&**right, index - left_len)
+                }
+            }
+        }
     }
 }
 
-impl ops::Index<ops::RangeTo<usize>> for TokenStream {
-    type Output = TokenSlice;
-
-    fn index(&self, index: ops::RangeTo<usize>) -> &TokenSlice {
-        Index::index(&**self, index)
-    }
-}
 
-impl ops::Index<ops::RangeFrom<usize>> for TokenStream {
-    type Output = TokenSlice;
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use syntax_pos::{Span, BytePos, NO_EXPANSION, DUMMY_SP};
+    use parse::token::{self, str_to_ident, Token};
+    use util::parser_testing::string_to_tts;
+    use std::rc::Rc;
 
-    fn index(&self, index: ops::RangeFrom<usize>) -> &TokenSlice {
-        Index::index(&**self, index)
+    fn sp(a: u32, b: u32) -> Span {
+        Span {
+            lo: BytePos(a),
+            hi: BytePos(b),
+            expn_id: NO_EXPANSION,
+        }
     }
-}
-
-impl ops::Index<ops::RangeFull> for TokenStream {
-    type Output = TokenSlice;
 
-    fn index(&self, _index: ops::RangeFull) -> &TokenSlice {
-        Index::index(&**self, _index)
+    fn as_paren_delimited_stream(tts: Vec<TokenTree>) -> TokenStream {
+        TokenStream::as_delimited_stream(tts, token::DelimToken::Paren)
     }
-}
-
-impl Index<usize> for TokenSlice {
-    type Output = TokenTree;
 
-    fn index(&self, index: usize) -> &TokenTree {
-        &self.0[index]
+    #[test]
+    fn test_concat() {
+        let test_res = TokenStream::from_tts(string_to_tts("foo::bar::baz".to_string()));
+        let test_fst = TokenStream::from_tts(string_to_tts("foo::bar".to_string()));
+        let test_snd = TokenStream::from_tts(string_to_tts("::baz".to_string()));
+        let eq_res = TokenStream::concat(test_fst, test_snd);
+        assert_eq!(test_res.len(), 5);
+        assert_eq!(eq_res.len(), 5);
+        assert_eq!(test_res.eq_unspanned(&eq_res), true);
     }
-}
-
-impl ops::Index<ops::Range<usize>> for TokenSlice {
-    type Output = TokenSlice;
 
-    fn index(&self, index: ops::Range<usize>) -> &TokenSlice {
-        TokenSlice::from_tts(&self.0[index])
+    #[test]
+    fn test_from_to_bijection() {
+        let test_start = string_to_tts("foo::bar(baz)".to_string());
+        let test_end = TokenStream::from_tts(string_to_tts("foo::bar(baz)".to_string())).to_tts();
+        assert_eq!(test_start, test_end)
     }
-}
 
-impl ops::Index<ops::RangeTo<usize>> for TokenSlice {
-    type Output = TokenSlice;
+    #[test]
+    fn test_to_from_bijection() {
+        let test_start = TokenStream::from_tts(string_to_tts("foo::bar(baz)".to_string()));
+        let test_end = TokenStream::from_tts(test_start.clone().to_tts());
+        assert_eq!(test_start, test_end)
+    }
 
-    fn index(&self, index: ops::RangeTo<usize>) -> &TokenSlice {
-        TokenSlice::from_tts(&self.0[index])
+    #[test]
+    fn test_eq_0() {
+        let test_res = TokenStream::from_tts(string_to_tts("foo".to_string()));
+        let test_eqs = TokenStream::from_tts(string_to_tts("foo".to_string()));
+        assert_eq!(test_res, test_eqs)
     }
-}
 
-impl ops::Index<ops::RangeFrom<usize>> for TokenSlice {
-    type Output = TokenSlice;
+    #[test]
+    fn test_eq_1() {
+        let test_res = TokenStream::from_tts(string_to_tts("::bar::baz".to_string()));
+        let test_eqs = TokenStream::from_tts(string_to_tts("::bar::baz".to_string()));
+        assert_eq!(test_res, test_eqs)
+    }
 
-    fn index(&self, index: ops::RangeFrom<usize>) -> &TokenSlice {
-        TokenSlice::from_tts(&self.0[index])
+    #[test]
+    fn test_eq_2() {
+        let test_res = TokenStream::from_tts(string_to_tts("foo::bar".to_string()));
+        let test_eqs = TokenStream::from_tts(string_to_tts("foo::bar::baz".to_string()));
+        assert_eq!(test_res, test_eqs.slice(0..3))
     }
-}
 
-impl ops::Index<ops::RangeFull> for TokenSlice {
-    type Output = TokenSlice;
+    #[test]
+    fn test_eq_3() {
+        let test_res = TokenStream::from_tts(string_to_tts("".to_string()));
+        let test_eqs = TokenStream::from_tts(string_to_tts("".to_string()));
+        assert_eq!(test_res, test_eqs)
+    }
 
-    fn index(&self, _index: ops::RangeFull) -> &TokenSlice {
-        TokenSlice::from_tts(&self.0[_index])
+    #[test]
+    fn test_diseq_0() {
+        let test_res = TokenStream::from_tts(string_to_tts("::bar::baz".to_string()));
+        let test_eqs = TokenStream::from_tts(string_to_tts("bar::baz".to_string()));
+        assert_eq!(test_res == test_eqs, false)
     }
-}
 
+    #[test]
+    fn test_diseq_1() {
+        let test_res = TokenStream::from_tts(string_to_tts("(bar,baz)".to_string()));
+        let test_eqs = TokenStream::from_tts(string_to_tts("bar,baz".to_string()));
+        assert_eq!(test_res == test_eqs, false)
+    }
 
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use ast;
-    use syntax_pos::{Span, BytePos, NO_EXPANSION, DUMMY_SP};
-    use parse::token::{self, str_to_ident, Token, Lit};
-    use util::parser_testing::string_to_tts;
-    use std::rc::Rc;
+    #[test]
+    fn test_slice_0() {
+        let test_res = TokenStream::from_tts(string_to_tts("foo::bar".to_string()));
+        let test_eqs = TokenStream::from_tts(string_to_tts("foo::bar::baz".to_string()));
+        assert_eq!(test_res, test_eqs.slice(0..3))
+    }
 
-    fn sp(a: u32, b: u32) -> Span {
-        Span {
-            lo: BytePos(a),
-            hi: BytePos(b),
-            expn_id: NO_EXPANSION,
-        }
+    #[test]
+    fn test_slice_1() {
+        let test_res = TokenStream::from_tts(string_to_tts("foo::bar::baz".to_string()))
+            .slice(2..3);
+        let test_eqs = TokenStream::from_tts(vec![TokenTree::Token(sp(5,8),
+                                                    token::Ident(str_to_ident("bar")))]);
+        assert_eq!(test_res, test_eqs)
     }
 
     #[test]
@@ -947,38 +925,6 @@ fn test_is_delimited() {
         assert_eq!(test5.is_delimited(), false);
     }
 
-    #[test]
-    fn test_is_assign() {
-        let test0 = TokenStream::from_tts(string_to_tts("= bar::baz".to_string()));
-        let test1 = TokenStream::from_tts(string_to_tts("= \"5\"".to_string()));
-        let test2 = TokenStream::from_tts(string_to_tts("= 5".to_string()));
-        let test3 = TokenStream::from_tts(string_to_tts("(foo = 10)".to_string()));
-        let test4 = TokenStream::from_tts(string_to_tts("= (foo,bar,baz)".to_string()));
-        let test5 = TokenStream::from_tts(string_to_tts("".to_string()));
-
-        assert_eq!(test0.is_assignment(), true);
-        assert_eq!(test1.is_assignment(), true);
-        assert_eq!(test2.is_assignment(), true);
-        assert_eq!(test3.is_assignment(), false);
-        assert_eq!(test4.is_assignment(), true);
-        assert_eq!(test5.is_assignment(), false);
-    }
-
-    #[test]
-    fn test_is_lit() {
-        let test0 = TokenStream::from_tts(string_to_tts("\"foo\"".to_string()));
-        let test1 = TokenStream::from_tts(string_to_tts("5".to_string()));
-        let test2 = TokenStream::from_tts(string_to_tts("foo".to_string()));
-        let test3 = TokenStream::from_tts(string_to_tts("foo::bar".to_string()));
-        let test4 = TokenStream::from_tts(string_to_tts("foo(bar)".to_string()));
-
-        assert_eq!(test0.is_lit(), true);
-        assert_eq!(test1.is_lit(), true);
-        assert_eq!(test2.is_lit(), false);
-        assert_eq!(test3.is_lit(), false);
-        assert_eq!(test4.is_lit(), false);
-    }
-
     #[test]
     fn test_is_ident() {
         let test0 = TokenStream::from_tts(string_to_tts("\"foo\"".to_string()));
@@ -994,62 +940,6 @@ fn test_is_ident() {
         assert_eq!(test4.is_ident(), false);
     }
 
-    #[test]
-    fn test_maybe_assignment() {
-        let test0_input = TokenStream::from_tts(string_to_tts("= bar::baz".to_string()));
-        let test1_input = TokenStream::from_tts(string_to_tts("= \"5\"".to_string()));
-        let test2_input = TokenStream::from_tts(string_to_tts("= 5".to_string()));
-        let test3_input = TokenStream::from_tts(string_to_tts("(foo = 10)".to_string()));
-        let test4_input = TokenStream::from_tts(string_to_tts("= (foo,bar,baz)".to_string()));
-        let test5_input = TokenStream::from_tts(string_to_tts("".to_string()));
-
-        let test0 = test0_input.maybe_assignment();
-        let test1 = test1_input.maybe_assignment();
-        let test2 = test2_input.maybe_assignment();
-        let test3 = test3_input.maybe_assignment();
-        let test4 = test4_input.maybe_assignment();
-        let test5 = test5_input.maybe_assignment();
-
-        let test0_expected = TokenStream::from_tts(vec![TokenTree::Token(sp(2, 5),
-                                                        token::Ident(str_to_ident("bar"))),
-                                       TokenTree::Token(sp(5, 7), token::ModSep),
-                                       TokenTree::Token(sp(7, 10),
-                                                        token::Ident(str_to_ident("baz")))]);
-        assert_eq!(test0, Some(&test0_expected[..]));
-
-        let test1_expected = TokenStream::from_tts(vec![TokenTree::Token(sp(2, 5),
-                                            token::Literal(Lit::Str_(token::intern("5")), None))]);
-        assert_eq!(test1, Some(&test1_expected[..]));
-
-        let test2_expected = TokenStream::from_tts(vec![TokenTree::Token( sp(2,3)
-                                       , token::Literal(
-                                           Lit::Integer(
-                                             token::intern(&(5.to_string()))),
-                                             None))]);
-        assert_eq!(test2, Some(&test2_expected[..]));
-
-        assert_eq!(test3, None);
-
-
-        let test4_tts = vec![TokenTree::Token(sp(3, 6), token::Ident(str_to_ident("foo"))),
-                             TokenTree::Token(sp(6, 7), token::Comma),
-                             TokenTree::Token(sp(7, 10), token::Ident(str_to_ident("bar"))),
-                             TokenTree::Token(sp(10, 11), token::Comma),
-                             TokenTree::Token(sp(11, 14), token::Ident(str_to_ident("baz")))];
-
-        let test4_expected = TokenStream::from_tts(vec![TokenTree::Delimited(sp(2, 15),
-                                                Rc::new(Delimited {
-                                                    delim: token::DelimToken::Paren,
-                                                    open_span: sp(2, 3),
-                                                    tts: test4_tts,
-                                                    close_span: sp(14, 15),
-                                                }))]);
-        assert_eq!(test4, Some(&test4_expected[..]));
-
-        assert_eq!(test5, None);
-
-    }
-
     #[test]
     fn test_maybe_delimited() {
         let test0_input = TokenStream::from_tts(string_to_tts("foo(bar::baz)".to_string()));
@@ -1074,7 +964,7 @@ fn test_maybe_delimited() {
                                        TokenTree::Token(sp(4, 6), token::ModSep),
                                        TokenTree::Token(sp(6, 9),
                                                         token::Ident(str_to_ident("baz")))]);
-        assert_eq!(test1, Some(&test1_expected[..]));
+        assert_eq!(test1, Some(test1_expected));
 
         let test2_expected = TokenStream::from_tts(vec![TokenTree::Token(sp(1, 4),
                                                         token::Ident(str_to_ident("foo"))),
@@ -1084,79 +974,13 @@ fn test_maybe_delimited() {
                                        TokenTree::Token(sp(8, 9), token::Comma),
                                        TokenTree::Token(sp(9, 12),
                                                         token::Ident(str_to_ident("baz")))]);
-        assert_eq!(test2, Some(&test2_expected[..]));
-
-        assert_eq!(test3, None);
-
-        assert_eq!(test4, None);
-
-        assert_eq!(test5, None);
-    }
-
-    #[test]
-    fn test_maybe_comma_list() {
-        let test0_input = TokenStream::from_tts(string_to_tts("foo(bar::baz)".to_string()));
-        let test1_input = TokenStream::from_tts(string_to_tts("(bar::baz)".to_string()));
-        let test2_input = TokenStream::from_tts(string_to_tts("(foo,bar,baz)".to_string()));
-        let test3_input = TokenStream::from_tts(string_to_tts("(foo::bar,bar,baz)".to_string()));
-        let test4_input = TokenStream::from_tts(string_to_tts("(foo,bar,baz)(zab,rab)"
-            .to_string()));
-        let test5_input = TokenStream::from_tts(string_to_tts("(foo,bar,baz)foo".to_string()));
-        let test6_input = TokenStream::from_tts(string_to_tts("".to_string()));
-        // The following is supported behavior!
-        let test7_input = TokenStream::from_tts(string_to_tts("(foo,bar,)".to_string()));
-
-        let test0 = test0_input.maybe_comma_list();
-        let test1 = test1_input.maybe_comma_list();
-        let test2 = test2_input.maybe_comma_list();
-        let test3 = test3_input.maybe_comma_list();
-        let test4 = test4_input.maybe_comma_list();
-        let test5 = test5_input.maybe_comma_list();
-        let test6 = test6_input.maybe_comma_list();
-        let test7 = test7_input.maybe_comma_list();
-
-        assert_eq!(test0, None);
-
-        let test1_stream = TokenStream::from_tts(vec![TokenTree::Token(sp(1, 4),
-                                                        token::Ident(str_to_ident("bar"))),
-                                       TokenTree::Token(sp(4, 6), token::ModSep),
-                                       TokenTree::Token(sp(6, 9),
-                                                        token::Ident(str_to_ident("baz")))]);
-
-        let test1_expected: Vec<&TokenSlice> = vec![&test1_stream[..]];
-        assert_eq!(test1, Some(test1_expected));
-
-        let test2_foo = TokenStream::from_tts(vec![TokenTree::Token(sp(1, 4),
-                                                        token::Ident(str_to_ident("foo")))]);
-        let test2_bar = TokenStream::from_tts(vec![TokenTree::Token(sp(5, 8),
-                                                        token::Ident(str_to_ident("bar")))]);
-        let test2_baz = TokenStream::from_tts(vec![TokenTree::Token(sp(9, 12),
-                                                        token::Ident(str_to_ident("baz")))]);
-        let test2_expected: Vec<&TokenSlice> = vec![&test2_foo[..], &test2_bar[..], &test2_baz[..]];
         assert_eq!(test2, Some(test2_expected));
 
-        let test3_path = TokenStream::from_tts(vec![TokenTree::Token(sp(1, 4),
-                                                        token::Ident(str_to_ident("foo"))),
-                                       TokenTree::Token(sp(4, 6), token::ModSep),
-                                       TokenTree::Token(sp(6, 9),
-                                                        token::Ident(str_to_ident("bar")))]);
-        let test3_bar = TokenStream::from_tts(vec![TokenTree::Token(sp(10, 13),
-                                                        token::Ident(str_to_ident("bar")))]);
-        let test3_baz = TokenStream::from_tts(vec![TokenTree::Token(sp(14, 17),
-                                                        token::Ident(str_to_ident("baz")))]);
-        let test3_expected: Vec<&TokenSlice> =
-            vec![&test3_path[..], &test3_bar[..], &test3_baz[..]];
-        assert_eq!(test3, Some(test3_expected));
+        assert_eq!(test3, None);
 
         assert_eq!(test4, None);
 
         assert_eq!(test5, None);
-
-        assert_eq!(test6, None);
-
-
-        let test7_expected: Vec<&TokenSlice> = vec![&test2_foo[..], &test2_bar[..]];
-        assert_eq!(test7, Some(test7_expected));
     }
 
     // pub fn maybe_ident(&self) -> Option<ast::Ident>
@@ -1175,86 +999,10 @@ fn test_maybe_ident() {
         assert_eq!(test4, None);
     }
 
-    // pub fn maybe_lit(&self) -> Option<token::Lit>
     #[test]
-    fn test_maybe_lit() {
-        let test0 = TokenStream::from_tts(string_to_tts("\"foo\"".to_string())).maybe_lit();
-        let test1 = TokenStream::from_tts(string_to_tts("5".to_string())).maybe_lit();
-        let test2 = TokenStream::from_tts(string_to_tts("foo".to_string())).maybe_lit();
-        let test3 = TokenStream::from_tts(string_to_tts("foo::bar".to_string())).maybe_lit();
-        let test4 = TokenStream::from_tts(string_to_tts("foo(bar)".to_string())).maybe_lit();
-
-        assert_eq!(test0, Some(Lit::Str_(token::intern("foo"))));
-        assert_eq!(test1, Some(Lit::Integer(token::intern(&(5.to_string())))));
-        assert_eq!(test2, None);
-        assert_eq!(test3, None);
-        assert_eq!(test4, None);
-    }
-
-    #[test]
-    fn test_maybe_path_prefix() {
-        let test0_input = TokenStream::from_tts(string_to_tts("foo(bar::baz)".to_string()));
-        let test1_input = TokenStream::from_tts(string_to_tts("(bar::baz)".to_string()));
-        let test2_input = TokenStream::from_tts(string_to_tts("(foo,bar,baz)".to_string()));
-        let test3_input = TokenStream::from_tts(string_to_tts("foo::bar(bar,baz)".to_string()));
-
-        let test0 = test0_input.maybe_path_prefix();
-        let test1 = test1_input.maybe_path_prefix();
-        let test2 = test2_input.maybe_path_prefix();
-        let test3 = test3_input.maybe_path_prefix();
-
-        let test0_tts = vec![TokenTree::Token(sp(4, 7), token::Ident(str_to_ident("bar"))),
-                             TokenTree::Token(sp(7, 9), token::ModSep),
-                             TokenTree::Token(sp(9, 12), token::Ident(str_to_ident("baz")))];
-
-        let test0_stream = TokenStream::from_tts(vec![TokenTree::Delimited(sp(3, 13),
-                                                               Rc::new(Delimited {
-                                                                   delim: token::DelimToken::Paren,
-                                                                   open_span: sp(3, 4),
-                                                                   tts: test0_tts,
-                                                                   close_span: sp(12, 13),
-                                                               }))]);
-
-        let test0_expected = Some((ast::Path::from_ident(sp(0, 3), str_to_ident("foo")),
-                                   &test0_stream[..]));
-        assert_eq!(test0, test0_expected);
-
-        assert_eq!(test1, None);
-        assert_eq!(test2, None);
-
-        let test3_path = ast::Path {
-            span: sp(0, 8),
-            global: false,
-            segments: vec![ast::PathSegment {
-                               identifier: str_to_ident("foo"),
-                               parameters: ast::PathParameters::none(),
-                           },
-                           ast::PathSegment {
-                               identifier: str_to_ident("bar"),
-                               parameters: ast::PathParameters::none(),
-                           }],
-        };
-
-        let test3_tts = vec![TokenTree::Token(sp(9, 12), token::Ident(str_to_ident("bar"))),
-                             TokenTree::Token(sp(12, 13), token::Comma),
-                             TokenTree::Token(sp(13, 16), token::Ident(str_to_ident("baz")))];
-
-        let test3_stream = TokenStream::from_tts(vec![TokenTree::Delimited(sp(8, 17),
-                                                               Rc::new(Delimited {
-                                                                   delim: token::DelimToken::Paren,
-                                                                   open_span: sp(8, 9),
-                                                                   tts: test3_tts,
-                                                                   close_span: sp(16, 17),
-                                                               }))]);
-        let test3_expected = Some((test3_path, &test3_stream[..]));
-        assert_eq!(test3, test3_expected);
-    }
-
-    #[test]
-    fn test_as_paren_delimited_stream() {
-        let test0 = TokenStream::as_paren_delimited_stream(string_to_tts("foo,bar,".to_string()));
-        let test1 = TokenStream::as_paren_delimited_stream(string_to_tts("baz(foo,bar)"
-            .to_string()));
+    fn test_as_delimited_stream() {
+        let test0 = as_paren_delimited_stream(string_to_tts("foo,bar,".to_string()));
+        let test1 = as_paren_delimited_stream(string_to_tts("baz(foo,bar)".to_string()));
 
         let test0_tts = vec![TokenTree::Token(sp(0, 3), token::Ident(str_to_ident("foo"))),
                              TokenTree::Token(sp(3, 4), token::Comma),
@@ -1294,5 +1042,4 @@ fn test_as_paren_delimited_stream() {
 
         assert_eq!(test1, test1_stream);
     }
-
 }
index 3d48024c8798573596a9777b2d7932e2ce52593a..1e873b5345c43d22f09da97e95eb203062b22c51 100644 (file)
 using namespace llvm;
 using namespace llvm::object;
 
-struct LLVMRustArchiveMember {
+struct RustArchiveMember {
   const char *filename;
   const char *name;
   Archive::Child child;
 
-  LLVMRustArchiveMember(): filename(NULL), name(NULL),
+  RustArchiveMember(): filename(NULL), name(NULL),
 #if LLVM_VERSION_MINOR >= 8
     child(NULL, NULL, NULL)
 #else
     child(NULL, NULL)
 #endif
   {}
-  ~LLVMRustArchiveMember() {}
+  ~RustArchiveMember() {}
 };
 
-typedef OwningBinary<Archive> RustArchive;
 
-extern "C" void*
+struct RustArchiveIterator {
+    Archive::child_iterator cur;
+    Archive::child_iterator end;
+#if LLVM_VERSION_MINOR >= 9
+    Error err;
+#endif
+};
+
+enum class LLVMRustArchiveKind {
+    Other,
+    GNU,
+    MIPS64,
+    BSD,
+    COFF,
+};
+
+static Archive::Kind
+from_rust(LLVMRustArchiveKind kind)
+{
+    switch (kind) {
+    case LLVMRustArchiveKind::GNU:
+        return Archive::K_GNU;
+    case LLVMRustArchiveKind::MIPS64:
+        return Archive::K_MIPS64;
+    case LLVMRustArchiveKind::BSD:
+        return Archive::K_BSD;
+    case LLVMRustArchiveKind::COFF:
+        return Archive::K_COFF;
+    default:
+      llvm_unreachable("Bad ArchiveKind.");
+  }
+}
+
+typedef OwningBinary<Archive> *LLVMRustArchiveRef;
+typedef RustArchiveMember *LLVMRustArchiveMemberRef;
+typedef Archive::Child *LLVMRustArchiveChildRef;
+typedef Archive::Child const *LLVMRustArchiveChildConstRef;
+typedef RustArchiveIterator *LLVMRustArchiveIteratorRef;
+
+extern "C" LLVMRustArchiveRef
 LLVMRustOpenArchive(char *path) {
     ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(path,
                                                                           -1,
@@ -66,20 +104,12 @@ LLVMRustOpenArchive(char *path) {
 }
 
 extern "C" void
-LLVMRustDestroyArchive(RustArchive *ar) {
+LLVMRustDestroyArchive(LLVMRustArchiveRef ar) {
     delete ar;
 }
 
-struct RustArchiveIterator {
-    Archive::child_iterator cur;
-    Archive::child_iterator end;
-#if LLVM_VERSION_MINOR >= 9
-    Error err;
-#endif
-};
-
-extern "C" RustArchiveIterator*
-LLVMRustArchiveIteratorNew(RustArchive *ra) {
+extern "C" LLVMRustArchiveIteratorRef
+LLVMRustArchiveIteratorNew(LLVMRustArchiveRef ra) {
     Archive *ar = ra->getBinary();
     RustArchiveIterator *rai = new RustArchiveIterator();
 #if LLVM_VERSION_MINOR <= 8
@@ -95,8 +125,8 @@ LLVMRustArchiveIteratorNew(RustArchive *ra) {
     return rai;
 }
 
-extern "C" const Archive::Child*
-LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) {
+extern "C" LLVMRustArchiveChildConstRef
+LLVMRustArchiveIteratorNext(LLVMRustArchiveIteratorRef rai) {
 #if LLVM_VERSION_MINOR >= 9
     if (rai->err) {
         LLVMRustSetLastError(toString(std::move(rai->err)).c_str());
@@ -122,17 +152,17 @@ LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) {
 }
 
 extern "C" void
-LLVMRustArchiveChildFree(Archive::Child *child) {
+LLVMRustArchiveChildFree(LLVMRustArchiveChildRef child) {
     delete child;
 }
 
 extern "C" void
-LLVMRustArchiveIteratorFree(RustArchiveIterator *rai) {
+LLVMRustArchiveIteratorFree(LLVMRustArchiveIteratorRef rai) {
     delete rai;
 }
 
 extern "C" const char*
-LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) {
+LLVMRustArchiveChildName(LLVMRustArchiveChildConstRef child, size_t *size) {
     ErrorOr<StringRef> name_or_err = child->getName();
     if (name_or_err.getError())
         return NULL;
@@ -142,7 +172,7 @@ LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) {
 }
 
 extern "C" const char*
-LLVMRustArchiveChildData(Archive::Child *child, size_t *size) {
+LLVMRustArchiveChildData(LLVMRustArchiveChildRef child, size_t *size) {
     StringRef buf;
     ErrorOr<StringRef> buf_or_err = child->getBuffer();
     if (buf_or_err.getError()) {
@@ -154,9 +184,10 @@ LLVMRustArchiveChildData(Archive::Child *child, size_t *size) {
     return buf.data();
 }
 
-extern "C" LLVMRustArchiveMember*
-LLVMRustArchiveMemberNew(char *Filename, char *Name, Archive::Child *child) {
-    LLVMRustArchiveMember *Member = new LLVMRustArchiveMember;
+extern "C" LLVMRustArchiveMemberRef
+LLVMRustArchiveMemberNew(char *Filename, char *Name,
+                        LLVMRustArchiveChildRef child) {
+    RustArchiveMember *Member = new RustArchiveMember;
     Member->filename = Filename;
     Member->name = Name;
     if (child)
@@ -165,22 +196,23 @@ LLVMRustArchiveMemberNew(char *Filename, char *Name, Archive::Child *child) {
 }
 
 extern "C" void
-LLVMRustArchiveMemberFree(LLVMRustArchiveMember *Member) {
+LLVMRustArchiveMemberFree(LLVMRustArchiveMemberRef Member) {
     delete Member;
 }
 
-extern "C" int
+extern "C" LLVMRustResult
 LLVMRustWriteArchive(char *Dst,
                      size_t NumMembers,
-                     const LLVMRustArchiveMember **NewMembers,
+                     const LLVMRustArchiveMemberRef *NewMembers,
                      bool WriteSymbtab,
-                     Archive::Kind Kind) {
+                     LLVMRustArchiveKind rust_kind) {
 
 #if LLVM_VERSION_MINOR <= 8
   std::vector<NewArchiveIterator> Members;
 #else
   std::vector<NewArchiveMember> Members;
 #endif
+  auto Kind = from_rust(rust_kind);
 
   for (size_t i = 0; i < NumMembers; i++) {
     auto Member = NewMembers[i];
@@ -190,7 +222,7 @@ LLVMRustWriteArchive(char *Dst,
       Expected<NewArchiveMember> MOrErr = NewArchiveMember::getFile(Member->filename, true);
       if (!MOrErr) {
         LLVMRustSetLastError(toString(MOrErr.takeError()).c_str());
-        return -1;
+        return LLVMRustResult::Failure;
       }
       Members.push_back(std::move(*MOrErr));
 #elif LLVM_VERSION_MINOR == 8
@@ -205,7 +237,7 @@ LLVMRustWriteArchive(char *Dst,
       Expected<NewArchiveMember> MOrErr = NewArchiveMember::getOldMember(Member->child, true);
       if (!MOrErr) {
         LLVMRustSetLastError(toString(MOrErr.takeError()).c_str());
-        return -1;
+        return LLVMRustResult::Failure;
       }
       Members.push_back(std::move(*MOrErr));
 #endif
@@ -217,7 +249,7 @@ LLVMRustWriteArchive(char *Dst,
   auto pair = writeArchive(Dst, Members, WriteSymbtab, Kind, true);
 #endif
   if (!pair.second)
-    return 0;
+    return LLVMRustResult::Success;
   LLVMRustSetLastError(pair.second.message().c_str());
-  return -1;
+  return LLVMRustResult::Failure;
 }
diff --git a/src/rustllvm/ExecutionEngineWrapper.cpp b/src/rustllvm/ExecutionEngineWrapper.cpp
deleted file mode 100644 (file)
index b26ab44..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#include "rustllvm.h"
-
-#include "llvm/ExecutionEngine/SectionMemoryManager.h"
-
-using namespace llvm;
-using namespace llvm::sys;
-using namespace llvm::object;
-
-class RustJITMemoryManager : public SectionMemoryManager
-{
-    typedef SectionMemoryManager Base;
-
-    public:
-
-    RustJITMemoryManager() {}
-
-    uint64_t getSymbolAddress(const std::string &Name) override
-    {
-        return Base::getSymbolAddress(Name);
-    }
-};
-
-DEFINE_SIMPLE_CONVERSION_FUNCTIONS(RustJITMemoryManager, LLVMRustJITMemoryManagerRef)
-
-extern "C" LLVMBool LLVMRustLoadDynamicLibrary(const char *path)
-{
-    std::string err;
-    DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(path, &err);
-
-    if (!lib.isValid())
-        LLVMRustSetLastError(err.c_str());
-
-    return lib.isValid();
-}
-
-// Calls LLVMAddModule;
-// exists for consistency with LLVMExecutionEngineRemoveModule
-extern "C" void LLVMExecutionEngineAddModule(
-    LLVMExecutionEngineRef eeref, LLVMModuleRef mref)
-{
-#ifdef _WIN32
-    // On Windows, MCJIT must generate ELF objects
-    std::string target = getProcessTriple();
-    target += "-elf";
-    target = Triple::normalize(target);
-    unwrap(mref)->setTargetTriple(target);
-#endif
-    LLVMAddModule(eeref, mref);
-}
-
-// LLVMRemoveModule exists in LLVM's C bindings,
-// but it requires pointless parameters
-extern "C" LLVMBool LLVMExecutionEngineRemoveModule(
-    LLVMExecutionEngineRef eeref, LLVMModuleRef mref)
-{
-    ExecutionEngine *ee = unwrap(eeref);
-    Module *m = unwrap(mref);
-
-    return ee->removeModule(m);
-}
-
-extern "C" LLVMExecutionEngineRef LLVMBuildExecutionEngine(LLVMModuleRef mod)
-{
-    // These are necessary for code generation to work properly.
-    InitializeNativeTarget();
-    InitializeNativeTargetAsmPrinter();
-    InitializeNativeTargetAsmParser();
-
-#ifdef _WIN32
-    // On Windows, MCJIT must generate ELF objects
-    std::string target = getProcessTriple();
-    target += "-elf";
-    target = Triple::normalize(target);
-    unwrap(mod)->setTargetTriple(target);
-#endif
-
-    std::string error_str;
-    TargetOptions options;
-
-    RustJITMemoryManager *mm = new RustJITMemoryManager;
-
-    ExecutionEngine *ee =
-        EngineBuilder(std::unique_ptr<Module>(unwrap(mod)))
-            .setMCJITMemoryManager(std::unique_ptr<RustJITMemoryManager>(mm))
-            .setEngineKind(EngineKind::JIT)
-            .setErrorStr(&error_str)
-            .setTargetOptions(options)
-            .create();
-
-    if (!ee)
-        LLVMRustSetLastError(error_str.c_str());
-
-    return wrap(ee);
-}
-
-extern "C" void LLVMExecutionEngineFinalizeObject(LLVMExecutionEngineRef eeref)
-{
-    ExecutionEngine *ee = unwrap(eeref);
-
-    ee->finalizeObject();
-}
index a1276060271bbb09f2b409417fd814477a51c206..3a20bb2714ece5b7967f9ee0eb698cd46d3a11dd 100644 (file)
@@ -17,6 +17,7 @@
 #include "llvm/Support/Host.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/IR/AutoUpgrade.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetSubtargetInfo.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
@@ -54,41 +55,48 @@ LLVMInitializePasses() {
   initializeTarget(Registry);
 }
 
-
-enum class SupportedPassKind {
+enum class LLVMRustPassKind {
+  Other,
   Function,
   Module,
-  Unsupported
 };
 
-extern "C" Pass*
+static LLVMRustPassKind
+to_rust(PassKind kind)
+{
+  switch (kind) {
+  case PT_Function:
+      return LLVMRustPassKind::Function;
+  case PT_Module:
+      return LLVMRustPassKind::Module;
+  default:
+      return LLVMRustPassKind::Other;
+  }
+}
+
+extern "C" LLVMPassRef
 LLVMRustFindAndCreatePass(const char *PassName) {
     StringRef SR(PassName);
     PassRegistry *PR = PassRegistry::getPassRegistry();
 
     const PassInfo *PI = PR->getPassInfo(SR);
     if (PI) {
-        return PI->createPass();
+      return wrap(PI->createPass());
     }
     return NULL;
 }
 
-extern "C" SupportedPassKind
-LLVMRustPassKind(Pass *pass) {
-    assert(pass);
-    PassKind passKind = pass->getPassKind();
-    if (passKind == PT_Module) {
-        return SupportedPassKind::Module;
-    } else if (passKind == PT_Function) {
-        return SupportedPassKind::Function;
-    } else {
-        return SupportedPassKind::Unsupported;
-    }
+extern "C" LLVMRustPassKind
+LLVMRustPassKind(LLVMPassRef rust_pass) {
+    assert(rust_pass);
+    Pass *pass = unwrap(rust_pass);
+    return to_rust(pass->getPassKind());
 }
 
 extern "C" void
-LLVMRustAddPass(LLVMPassManagerRef PM, Pass *pass) {
-    assert(pass);
+LLVMRustAddPass(LLVMPassManagerRef PM, LLVMPassRef rust_pass) {
+    assert(rust_pass);
+    Pass *pass = unwrap(rust_pass);
     PassManagerBase *pm = unwrap(PM);
     pm->add(pass);
 }
@@ -162,13 +170,69 @@ LLVMRustHasFeature(LLVMTargetMachineRef TM,
     return (Bits & FeatureEntry->Value) == FeatureEntry->Value;
 }
 
+enum class LLVMRustCodeModel {
+    Other,
+    Default,
+    JITDefault,
+    Small,
+    Kernel,
+    Medium,
+    Large,
+};
+
+static CodeModel::Model
+from_rust(LLVMRustCodeModel model)
+{
+    switch (model) {
+    case LLVMRustCodeModel::Default:
+        return CodeModel::Default;
+    case LLVMRustCodeModel::JITDefault:
+        return CodeModel::JITDefault;
+    case LLVMRustCodeModel::Small:
+        return CodeModel::Small;
+    case LLVMRustCodeModel::Kernel:
+        return CodeModel::Kernel;
+    case LLVMRustCodeModel::Medium:
+        return CodeModel::Medium;
+    case LLVMRustCodeModel::Large:
+        return CodeModel::Large;
+    default:
+        llvm_unreachable("Bad CodeModel.");
+  }
+}
+
+enum class LLVMRustCodeGenOptLevel {
+    Other,
+    None,
+    Less,
+    Default,
+    Aggressive,
+};
+
+static CodeGenOpt::Level
+from_rust(LLVMRustCodeGenOptLevel level)
+{
+    switch (level) {
+    case LLVMRustCodeGenOptLevel::None:
+        return CodeGenOpt::None;
+    case LLVMRustCodeGenOptLevel::Less:
+        return CodeGenOpt::Less;
+    case LLVMRustCodeGenOptLevel::Default:
+        return CodeGenOpt::Default;
+    case LLVMRustCodeGenOptLevel::Aggressive:
+        return CodeGenOpt::Aggressive;
+    default:
+        llvm_unreachable("Bad CodeGenOptLevel.");
+  }
+}
+
 extern "C" LLVMTargetMachineRef
 LLVMRustCreateTargetMachine(const char *triple,
                             const char *cpu,
                             const char *feature,
-                            CodeModel::Model CM,
+                            LLVMRustCodeModel rust_CM,
                             LLVMRelocMode Reloc,
-                            CodeGenOpt::Level OptLevel,
+                            LLVMRustCodeGenOptLevel rust_OptLevel,
                             bool UseSoftFloat,
                             bool PositionIndependentExecutable,
                             bool FunctionSections,
@@ -179,6 +243,9 @@ LLVMRustCreateTargetMachine(const char *triple,
 #else
     Optional<Reloc::Model> RM;
 #endif
+    auto CM = from_rust(rust_CM);
+    auto OptLevel = from_rust(rust_OptLevel);
+
     switch (Reloc){
         case LLVMRelocStatic:
             RM = Reloc::Static;
@@ -251,14 +318,14 @@ LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM,
 
 extern "C" void
 LLVMRustConfigurePassManagerBuilder(LLVMPassManagerBuilderRef PMB,
-                                    CodeGenOpt::Level OptLevel,
+                                   LLVMRustCodeGenOptLevel OptLevel,
                                     bool MergeFunctions,
                                     bool SLPVectorize,
                                     bool LoopVectorize) {
     // Ignore mergefunc for now as enabling it causes crashes.
     //unwrap(PMB)->MergeFunctions = MergeFunctions;
     unwrap(PMB)->SLPVectorize = SLPVectorize;
-    unwrap(PMB)->OptLevel = OptLevel;
+    unwrap(PMB)->OptLevel = from_rust(OptLevel);
     unwrap(PMB)->LoopVectorize = LoopVectorize;
 }
 
@@ -295,10 +362,17 @@ extern "C" void
 LLVMRustRunFunctionPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) {
     llvm::legacy::FunctionPassManager *P = unwrap<llvm::legacy::FunctionPassManager>(PM);
     P->doInitialization();
+
+    // Upgrade all calls to old intrinsics first.
+    for (Module::iterator I = unwrap(M)->begin(),
+         E = unwrap(M)->end(); I != E;)
+        UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
+
     for (Module::iterator I = unwrap(M)->begin(),
          E = unwrap(M)->end(); I != E; ++I)
         if (!I->isDeclaration())
             P->run(*I);
+
     P->doFinalization();
 }
 
@@ -314,13 +388,33 @@ LLVMRustSetLLVMOptions(int Argc, char **Argv) {
     cl::ParseCommandLineOptions(Argc, Argv);
 }
 
-extern "C" bool
+enum class LLVMRustFileType {
+    Other,
+    AssemblyFile,
+    ObjectFile,
+};
+
+static TargetMachine::CodeGenFileType
+from_rust(LLVMRustFileType type)
+{
+    switch (type) {
+    case LLVMRustFileType::AssemblyFile:
+        return TargetMachine::CGFT_AssemblyFile;
+    case LLVMRustFileType::ObjectFile:
+        return TargetMachine::CGFT_ObjectFile;
+    default:
+        llvm_unreachable("Bad FileType.");
+  }
+}
+
+extern "C" LLVMRustResult
 LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
                         LLVMPassManagerRef PMR,
                         LLVMModuleRef M,
                         const char *path,
-                        TargetMachine::CodeGenFileType FileType) {
+                        LLVMRustFileType rust_FileType) {
   llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
+  auto FileType = from_rust(rust_FileType);
 
   std::string ErrorInfo;
   std::error_code EC;
@@ -329,7 +423,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
     ErrorInfo = EC.message();
   if (ErrorInfo != "") {
     LLVMRustSetLastError(ErrorInfo.c_str());
-    return false;
+    return LLVMRustResult::Failure;
   }
 
   unwrap(Target)->addPassesToEmitFile(*PM, OS, FileType, false);
@@ -339,7 +433,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
   // stream (OS), so the only real safe place to delete this is here? Don't we
   // wish this was written in Rust?
   delete PM;
-  return true;
+  return LLVMRustResult::Success;
 }
 
 extern "C" void
index c0db3f68a76208904fd788122dfc19fdfaccf099..e1c6dd07d2b3856a5a2050a8551474123f7a56c3 100644 (file)
@@ -1,2 +1,16 @@
 This directory currently contains some LLVM support code. This will generally
 be sent upstream to LLVM in time; for now it lives here.
+
+NOTE: the LLVM C++ ABI is subject to between-version breakage and must *never*
+be exposed to Rust. To allow for easy auditing of that, all Rust-exposed types
+must be typedef-ed as "LLVMXyz", or "LLVMRustXyz" if they were defined here.
+
+Functions that return a failure status and leave the error in
+the LLVM last error should return an LLVMRustResult rather than an
+int or anything to avoid confusion.
+
+When translating enums, add a single `Other` variant as the first
+one to allow for new variants to be added. It should abort when used
+as an input.
+
+All other types must not be typedef-ed as such.
index bc38245d3512761061e367820c2d4cc692b63af2..0da25e7ac57b7a7eea4628692251f0b92743d3cd 100644 (file)
@@ -13,6 +13,7 @@
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
+#include "llvm/IR/Instructions.h"
 
 #include "llvm/IR/CallSite.h"
 
@@ -27,6 +28,30 @@ using namespace llvm;
 using namespace llvm::sys;
 using namespace llvm::object;
 
+// LLVMAtomicOrdering is already an enum - don't create another
+// one.
+static AtomicOrdering from_rust(LLVMAtomicOrdering Ordering) {
+  switch (Ordering) {
+    case LLVMAtomicOrderingNotAtomic:
+        return AtomicOrdering::NotAtomic;
+    case LLVMAtomicOrderingUnordered:
+        return AtomicOrdering::Unordered;
+    case LLVMAtomicOrderingMonotonic:
+        return AtomicOrdering::Monotonic;
+    case LLVMAtomicOrderingAcquire:
+        return AtomicOrdering::Acquire;
+    case LLVMAtomicOrderingRelease:
+        return AtomicOrdering::Release;
+    case LLVMAtomicOrderingAcquireRelease:
+        return AtomicOrdering::AcquireRelease;
+    case LLVMAtomicOrderingSequentiallyConsistent:
+        return AtomicOrdering::SequentiallyConsistent;
+  }
+
+  llvm_unreachable("Invalid LLVMAtomicOrdering value!");
+}
+
+
 static char *LastError;
 
 extern "C" LLVMMemoryBufferRef
@@ -57,45 +82,30 @@ LLVMRustSetNormalizedTarget(LLVMModuleRef M, const char *triple) {
     unwrap(M)->setTargetTriple(Triple::normalize(triple));
 }
 
-extern "C" LLVMValueRef LLVMRustConstSmallInt(LLVMTypeRef IntTy, unsigned N,
-                                              LLVMBool SignExtend) {
-  return LLVMConstInt(IntTy, (unsigned long long)N, SignExtend);
-}
-
-extern "C" LLVMValueRef LLVMRustConstInt(LLVMTypeRef IntTy,
-           unsigned N_hi,
-           unsigned N_lo,
-           LLVMBool SignExtend) {
-  unsigned long long N = N_hi;
-  N <<= 32;
-  N |= N_lo;
-  return LLVMConstInt(IntTy, N, SignExtend);
-}
-
 extern "C" void LLVMRustPrintPassTimings() {
   raw_fd_ostream OS (2, false); // stderr.
   TimerGroup::printAll(OS);
 }
 
-extern "C" LLVMValueRef LLVMGetNamedValue(LLVMModuleRef M,
-                                          const char* Name) {
+extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M,
+                                             const char* Name) {
     return wrap(unwrap(M)->getNamedValue(Name));
 }
 
-extern "C" LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M,
-                                                const char* Name,
-                                                LLVMTypeRef FunctionTy) {
+extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
+                                                   const char* Name,
+                                                   LLVMTypeRef FunctionTy) {
   return wrap(unwrap(M)->getOrInsertFunction(Name,
                                              unwrap<FunctionType>(FunctionTy)));
 }
 
-extern "C" LLVMValueRef LLVMGetOrInsertGlobal(LLVMModuleRef M,
-                                              const char* Name,
-                                              LLVMTypeRef Ty) {
+extern "C" LLVMValueRef LLVMRustGetOrInsertGlobal(LLVMModuleRef M,
+                                                 const char* Name,
+                                                 LLVMTypeRef Ty) {
   return wrap(unwrap(M)->getOrInsertGlobal(Name, unwrap(Ty)));
 }
 
-extern "C" LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) {
+extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
   return wrap(Type::getMetadataTy(*unwrap(C)));
 }
 
@@ -110,7 +120,10 @@ extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned index,
 }
 
 
-extern "C" void LLVMAddDereferenceableCallSiteAttr(LLVMValueRef Instr, unsigned idx, uint64_t b) {
+extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
+                                                      unsigned idx,
+                                                      uint64_t b)
+{
   CallSite Call = CallSite(unwrap<Instruction>(Instr));
   AttrBuilder B;
   B.addDereferenceableAttr(b);
@@ -120,38 +133,50 @@ extern "C" void LLVMAddDereferenceableCallSiteAttr(LLVMValueRef Instr, unsigned
                                                          idx, B)));
 }
 
-extern "C" void LLVMAddFunctionAttribute(LLVMValueRef Fn, unsigned index,
-                                         uint64_t Val) {
+extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn,
+                                            unsigned index,
+                                            uint64_t Val)
+{
   Function *A = unwrap<Function>(Fn);
   AttrBuilder B;
   B.addRawValue(Val);
   A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
 }
 
-extern "C" void LLVMAddDereferenceableAttr(LLVMValueRef Fn, unsigned index, uint64_t bytes) {
+extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn,
+                                              unsigned index,
+                                              uint64_t bytes)
+{
   Function *A = unwrap<Function>(Fn);
   AttrBuilder B;
   B.addDereferenceableAttr(bytes);
   A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
 }
 
-extern "C" void LLVMAddFunctionAttrString(LLVMValueRef Fn, unsigned index, const char *Name) {
+extern "C" void LLVMRustAddFunctionAttrString(LLVMValueRef Fn,
+                                             unsigned index,
+                                             const char *Name)
+{
   Function *F = unwrap<Function>(Fn);
   AttrBuilder B;
   B.addAttribute(Name);
   F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
 }
 
-extern "C" void LLVMAddFunctionAttrStringValue(LLVMValueRef Fn, unsigned index,
-                                               const char *Name,
-                                               const char *Value) {
+extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
+                                                  unsigned index,
+                                                  const char *Name,
+                                                  const char *Value) {
   Function *F = unwrap<Function>(Fn);
   AttrBuilder B;
   B.addAttribute(Name, Value);
   F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
 }
 
-extern "C" void LLVMRemoveFunctionAttributes(LLVMValueRef Fn, unsigned index, uint64_t Val) {
+extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
+                                                unsigned index,
+                                                uint64_t Val)
+{
   Function *A = unwrap<Function>(Fn);
   const AttributeSet PAL = A->getAttributes();
   AttrBuilder B(Val);
@@ -161,7 +186,10 @@ extern "C" void LLVMRemoveFunctionAttributes(LLVMValueRef Fn, unsigned index, ui
   A->setAttributes(PALnew);
 }
 
-extern "C" void LLVMRemoveFunctionAttrString(LLVMValueRef fn, unsigned index, const char *Name) {
+extern "C" void LLVMRustRemoveFunctionAttrString(LLVMValueRef fn,
+                                                unsigned index,
+                                                const char *Name)
+{
   Function *f = unwrap<Function>(fn);
   LLVMContext &C = f->getContext();
   AttrBuilder B;
@@ -181,24 +209,24 @@ extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) {
     }
 }
 
-extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B,
-                                            LLVMValueRef source,
-                                            const char* Name,
-                                            AtomicOrdering order,
-                                            unsigned alignment) {
+extern "C" LLVMValueRef LLVMRustBuildAtomicLoad(LLVMBuilderRef B,
+                                               LLVMValueRef source,
+                                               const char* Name,
+                                               LLVMAtomicOrdering order,
+                                               unsigned alignment) {
     LoadInst* li = new LoadInst(unwrap(source),0);
-    li->setAtomic(order);
+    li->setAtomic(from_rust(order));
     li->setAlignment(alignment);
     return wrap(unwrap(B)->Insert(li, Name));
 }
 
-extern "C" LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef B,
-                                             LLVMValueRef val,
-                                             LLVMValueRef target,
-                                             AtomicOrdering order,
-                                             unsigned alignment) {
+extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
+                                                LLVMValueRef val,
+                                                LLVMValueRef target,
+                                                LLVMAtomicOrdering order,
+                                                unsigned alignment) {
     StoreInst* si = new StoreInst(unwrap(val),unwrap(target));
-    si->setAtomic(order);
+    si->setAtomic(from_rust(order));
     si->setAlignment(alignment);
     return wrap(unwrap(B)->Insert(si));
 }
@@ -207,54 +235,96 @@ extern "C" LLVMValueRef LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B,
                                                LLVMValueRef target,
                                                LLVMValueRef old,
                                                LLVMValueRef source,
-                                               AtomicOrdering order,
-                                               AtomicOrdering failure_order,
+                                               LLVMAtomicOrdering order,
+                                               LLVMAtomicOrdering failure_order,
                                                LLVMBool weak) {
-    AtomicCmpXchgInst* acxi = unwrap(B)->CreateAtomicCmpXchg(unwrap(target),
-                                                             unwrap(old),
-                                                             unwrap(source),
-                                                             order,
-                                                             failure_order);
+    AtomicCmpXchgInst* acxi = unwrap(B)->CreateAtomicCmpXchg(
+        unwrap(target),
+        unwrap(old),
+        unwrap(source),
+        from_rust(order),
+       from_rust(failure_order));
     acxi->setWeak(weak);
     return wrap(acxi);
 }
-extern "C" LLVMValueRef LLVMBuildAtomicFence(LLVMBuilderRef B,
-                                             AtomicOrdering order,
-                                             SynchronizationScope scope) {
-    return wrap(unwrap(B)->CreateFence(order, scope));
+
+enum class LLVMRustSynchronizationScope {
+    Other,
+    SingleThread,
+    CrossThread,
+};
+
+static SynchronizationScope
+from_rust(LLVMRustSynchronizationScope scope)
+{
+    switch (scope) {
+    case LLVMRustSynchronizationScope::SingleThread:
+        return SingleThread;
+    case LLVMRustSynchronizationScope::CrossThread:
+        return CrossThread;
+    default:
+        llvm_unreachable("bad SynchronizationScope.");
+    }
 }
 
-extern "C" void LLVMSetDebug(int Enabled) {
+extern "C" LLVMValueRef LLVMRustBuildAtomicFence(
+    LLVMBuilderRef B,
+    LLVMAtomicOrdering order,
+    LLVMRustSynchronizationScope scope)
+{
+    return wrap(unwrap(B)->CreateFence(from_rust(order), from_rust(scope)));
+}
+
+extern "C" void LLVMRustSetDebug(int Enabled) {
 #ifndef NDEBUG
   DebugFlag = Enabled;
 #endif
 }
 
-extern "C" LLVMValueRef LLVMInlineAsm(LLVMTypeRef Ty,
-                                      char *AsmString,
-                                      char *Constraints,
-                                      LLVMBool HasSideEffects,
-                                      LLVMBool IsAlignStack,
-                                      unsigned Dialect) {
+enum class LLVMRustAsmDialect {
+    Other,
+    Att,
+    Intel,
+};
+
+static InlineAsm::AsmDialect
+from_rust(LLVMRustAsmDialect dialect)
+{
+    switch (dialect) {
+    case LLVMRustAsmDialect::Att:
+        return InlineAsm::AD_ATT;
+    case LLVMRustAsmDialect::Intel:
+        return InlineAsm::AD_Intel;
+    default:
+        llvm_unreachable("bad AsmDialect.");
+    }
+}
+
+extern "C" LLVMValueRef LLVMRustInlineAsm(LLVMTypeRef Ty,
+                                         char *AsmString,
+                                         char *Constraints,
+                                         LLVMBool HasSideEffects,
+                                         LLVMBool IsAlignStack,
+                                         LLVMRustAsmDialect Dialect) {
     return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString,
                                Constraints, HasSideEffects,
-                               IsAlignStack, (InlineAsm::AsmDialect) Dialect));
+                               IsAlignStack, from_rust(Dialect)));
 }
 
-typedef DIBuilder* DIBuilderRef;
+typedef DIBuilder* LLVMRustDIBuilderRef;
 
-typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
+typedef struct LLVMOpaqueMetadata *LLVMRustMetadataRef;
 
 namespace llvm {
-DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef)
+DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMRustMetadataRef)
 
-inline Metadata **unwrap(LLVMMetadataRef *Vals) {
+inline Metadata **unwrap(LLVMRustMetadataRef *Vals) {
   return reinterpret_cast<Metadata**>(Vals);
 }
 }
 
 template<typename DIT>
-DIT* unwrapDIptr(LLVMMetadataRef ref) {
+DIT* unwrapDIptr(LLVMRustMetadataRef ref) {
     return (DIT*) (ref ? unwrap<MDNode>(ref) : NULL);
 }
 
@@ -266,11 +336,11 @@ extern "C" uint32_t LLVMRustDebugMetadataVersion() {
     return DEBUG_METADATA_VERSION;
 }
 
-extern "C" uint32_t LLVMVersionMinor() {
+extern "C" uint32_t LLVMRustVersionMinor() {
   return LLVM_VERSION_MINOR;
 }
 
-extern "C" uint32_t LLVMVersionMajor() {
+extern "C" uint32_t LLVMRustVersionMajor() {
   return LLVM_VERSION_MAJOR;
 }
 
@@ -280,20 +350,20 @@ extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M,
     unwrap(M)->addModuleFlag(Module::Warning, name, value);
 }
 
-extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) {
+extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
     return new DIBuilder(*unwrap(M));
 }
 
-extern "C" void LLVMDIBuilderDispose(DIBuilderRef Builder) {
+extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
     delete Builder;
 }
 
-extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder) {
+extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
     Builder->finalize();
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(
-    DIBuilderRef Builder,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateCompileUnit(
+    LLVMRustDIBuilderRef Builder,
     unsigned Lang,
     const char* File,
     const char* Dir,
@@ -312,17 +382,17 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(
                                            SplitName));
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderCreateFile(
-    DIBuilderRef Builder,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFile(
+    LLVMRustDIBuilderRef Builder,
     const char* Filename,
     const char* Directory) {
     return wrap(Builder->createFile(Filename, Directory));
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderCreateSubroutineType(
-    DIBuilderRef Builder,
-    LLVMMetadataRef File,
-    LLVMMetadataRef ParameterTypes) {
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateSubroutineType(
+    LLVMRustDIBuilderRef Builder,
+    LLVMRustMetadataRef File,
+    LLVMRustMetadataRef ParameterTypes) {
     return wrap(Builder->createSubroutineType(
 #if LLVM_VERSION_MINOR == 7
         unwrapDI<DIFile>(File),
@@ -330,22 +400,22 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateSubroutineType(
         DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderCreateFunction(
-    DIBuilderRef Builder,
-    LLVMMetadataRef Scope,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFunction(
+    LLVMRustDIBuilderRef Builder,
+    LLVMRustMetadataRef Scope,
     const char* Name,
     const char* LinkageName,
-    LLVMMetadataRef File,
+    LLVMRustMetadataRef File,
     unsigned LineNo,
-    LLVMMetadataRef Ty,
+    LLVMRustMetadataRef Ty,
     bool isLocalToUnit,
     bool isDefinition,
     unsigned ScopeLine,
     unsigned Flags,
     bool isOptimized,
     LLVMValueRef Fn,
-    LLVMMetadataRef TParam,
-    LLVMMetadataRef Decl) {
+    LLVMRustMetadataRef TParam,
+    LLVMRustMetadataRef Decl) {
 #if LLVM_VERSION_MINOR >= 8
     DITemplateParameterArray TParams =
         DITemplateParameterArray(unwrap<MDTuple>(TParam));
@@ -370,8 +440,8 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateFunction(
 #endif
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderCreateBasicType(
-    DIBuilderRef Builder,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateBasicType(
+    LLVMRustDIBuilderRef Builder,
     const char* Name,
     uint64_t SizeInBits,
     uint64_t AlignInBits,
@@ -381,9 +451,9 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateBasicType(
         AlignInBits, Encoding));
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderCreatePointerType(
-    DIBuilderRef Builder,
-    LLVMMetadataRef PointeeTy,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreatePointerType(
+    LLVMRustDIBuilderRef Builder,
+    LLVMRustMetadataRef PointeeTy,
     uint64_t SizeInBits,
     uint64_t AlignInBits,
     const char* Name) {
@@ -391,19 +461,19 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreatePointerType(
         unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, Name));
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderCreateStructType(
-    DIBuilderRef Builder,
-    LLVMMetadataRef Scope,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStructType(
+    LLVMRustDIBuilderRef Builder,
+    LLVMRustMetadataRef Scope,
     const char* Name,
-    LLVMMetadataRef File,
+    LLVMRustMetadataRef File,
     unsigned LineNumber,
     uint64_t SizeInBits,
     uint64_t AlignInBits,
     unsigned Flags,
-    LLVMMetadataRef DerivedFrom,
-    LLVMMetadataRef Elements,
+    LLVMRustMetadataRef DerivedFrom,
+    LLVMRustMetadataRef Elements,
     unsigned RunTimeLang,
-    LLVMMetadataRef VTableHolder,
+    LLVMRustMetadataRef VTableHolder,
     const char *UniqueId) {
     return wrap(Builder->createStructType(
         unwrapDI<DIDescriptor>(Scope),
@@ -421,17 +491,17 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateStructType(
         ));
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderCreateMemberType(
-    DIBuilderRef Builder,
-    LLVMMetadataRef Scope,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateMemberType(
+    LLVMRustDIBuilderRef Builder,
+    LLVMRustMetadataRef Scope,
     const char* Name,
-    LLVMMetadataRef File,
+    LLVMRustMetadataRef File,
     unsigned LineNo,
     uint64_t SizeInBits,
     uint64_t AlignInBits,
     uint64_t OffsetInBits,
     unsigned Flags,
-    LLVMMetadataRef Ty) {
+    LLVMRustMetadataRef Ty) {
     return wrap(Builder->createMemberType(
         unwrapDI<DIDescriptor>(Scope), Name,
         unwrapDI<DIFile>(File), LineNo,
@@ -439,10 +509,10 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateMemberType(
         unwrapDI<DIType>(Ty)));
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(
-    DIBuilderRef Builder,
-    LLVMMetadataRef Scope,
-    LLVMMetadataRef File,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
+    LLVMRustDIBuilderRef Builder,
+    LLVMRustMetadataRef Scope,
+    LLVMRustMetadataRef File,
     unsigned Line,
     unsigned Col) {
     return wrap(Builder->createLexicalBlock(
@@ -451,17 +521,17 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(
         ));
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderCreateStaticVariable(
-    DIBuilderRef Builder,
-    LLVMMetadataRef Context,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStaticVariable(
+    LLVMRustDIBuilderRef Builder,
+    LLVMRustMetadataRef Context,
     const char* Name,
     const char* LinkageName,
-    LLVMMetadataRef File,
+    LLVMRustMetadataRef File,
     unsigned LineNo,
-    LLVMMetadataRef Ty,
+    LLVMRustMetadataRef Ty,
     bool isLocalToUnit,
     LLVMValueRef Val,
-    LLVMMetadataRef Decl = NULL) {
+    LLVMRustMetadataRef Decl = NULL) {
     return wrap(Builder->createGlobalVariable(unwrapDI<DIDescriptor>(Context),
         Name,
         LinkageName,
@@ -473,14 +543,14 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateStaticVariable(
         unwrapDIptr<MDNode>(Decl)));
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderCreateVariable(
-    DIBuilderRef Builder,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable(
+    LLVMRustDIBuilderRef Builder,
     unsigned Tag,
-    LLVMMetadataRef Scope,
+    LLVMRustMetadataRef Scope,
     const char* Name,
-    LLVMMetadataRef File,
+    LLVMRustMetadataRef File,
     unsigned LineNo,
-    LLVMMetadataRef Ty,
+    LLVMRustMetadataRef Ty,
     bool AlwaysPreserve,
     unsigned Flags,
     int64_t* AddrOps,
@@ -509,50 +579,50 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateVariable(
 #endif
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderCreateArrayType(
-    DIBuilderRef Builder,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateArrayType(
+    LLVMRustDIBuilderRef Builder,
     uint64_t Size,
     uint64_t AlignInBits,
-    LLVMMetadataRef Ty,
-    LLVMMetadataRef Subscripts) {
+    LLVMRustMetadataRef Ty,
+    LLVMRustMetadataRef Subscripts) {
     return wrap(Builder->createArrayType(Size, AlignInBits,
         unwrapDI<DIType>(Ty),
         DINodeArray(unwrapDI<MDTuple>(Subscripts))
     ));
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderCreateVectorType(
-    DIBuilderRef Builder,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVectorType(
+    LLVMRustDIBuilderRef Builder,
     uint64_t Size,
     uint64_t AlignInBits,
-    LLVMMetadataRef Ty,
-    LLVMMetadataRef Subscripts) {
+    LLVMRustMetadataRef Ty,
+    LLVMRustMetadataRef Subscripts) {
     return wrap(Builder->createVectorType(Size, AlignInBits,
         unwrapDI<DIType>(Ty),
         DINodeArray(unwrapDI<MDTuple>(Subscripts))
     ));
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(
-    DIBuilderRef Builder,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateSubrange(
+    LLVMRustDIBuilderRef Builder,
     int64_t Lo,
     int64_t Count) {
     return wrap(Builder->getOrCreateSubrange(Lo, Count));
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(
-    DIBuilderRef Builder,
-    LLVMMetadataRef* Ptr,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateArray(
+    LLVMRustDIBuilderRef Builder,
+    LLVMRustMetadataRef* Ptr,
     unsigned Count) {
     Metadata **DataValue = unwrap(Ptr);
     return wrap(Builder->getOrCreateArray(
         ArrayRef<Metadata*>(DataValue, Count)).get());
 }
 
-extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
-    DIBuilderRef Builder,
+extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
+    LLVMRustDIBuilderRef Builder,
     LLVMValueRef Val,
-    LLVMMetadataRef VarInfo,
+    LLVMRustMetadataRef VarInfo,
     int64_t* AddrOps,
     unsigned AddrOpsCount,
     LLVMValueRef DL,
@@ -566,10 +636,10 @@ extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
         unwrap(InsertAtEnd)));
 }
 
-extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
-    DIBuilderRef Builder,
+extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareBefore(
+    LLVMRustDIBuilderRef Builder,
     LLVMValueRef Val,
-    LLVMMetadataRef VarInfo,
+    LLVMRustMetadataRef VarInfo,
     int64_t* AddrOps,
     unsigned AddrOpsCount,
     LLVMValueRef DL,
@@ -583,24 +653,24 @@ extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
         unwrap<Instruction>(InsertBefore)));
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerator(
-    DIBuilderRef Builder,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerator(
+    LLVMRustDIBuilderRef Builder,
     const char* Name,
     uint64_t Val)
 {
     return wrap(Builder->createEnumerator(Name, Val));
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(
-    DIBuilderRef Builder,
-    LLVMMetadataRef Scope,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerationType(
+    LLVMRustDIBuilderRef Builder,
+    LLVMRustMetadataRef Scope,
     const char* Name,
-    LLVMMetadataRef File,
+    LLVMRustMetadataRef File,
     unsigned LineNumber,
     uint64_t SizeInBits,
     uint64_t AlignInBits,
-    LLVMMetadataRef Elements,
-    LLVMMetadataRef ClassType)
+    LLVMRustMetadataRef Elements,
+    LLVMRustMetadataRef ClassType)
 {
     return wrap(Builder->createEnumerationType(
         unwrapDI<DIDescriptor>(Scope),
@@ -613,16 +683,16 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(
         unwrapDI<DIType>(ClassType)));
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderCreateUnionType(
-    DIBuilderRef Builder,
-    LLVMMetadataRef Scope,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateUnionType(
+    LLVMRustDIBuilderRef Builder,
+    LLVMRustMetadataRef Scope,
     const char* Name,
-    LLVMMetadataRef File,
+    LLVMRustMetadataRef File,
     unsigned LineNumber,
     uint64_t SizeInBits,
     uint64_t AlignInBits,
     unsigned Flags,
-    LLVMMetadataRef Elements,
+    LLVMRustMetadataRef Elements,
     unsigned RunTimeLang,
     const char* UniqueId)
 {
@@ -640,12 +710,12 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateUnionType(
         ));
 }
 
-extern "C" LLVMMetadataRef LLVMDIBuilderCreateTemplateTypeParameter(
-    DIBuilderRef Builder,
-    LLVMMetadataRef Scope,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
+    LLVMRustDIBuilderRef Builder,
+    LLVMRustMetadataRef Scope,
     const char* Name,
-    LLVMMetadataRef Ty,
-    LLVMMetadataRef File,
+    LLVMRustMetadataRef Ty,
+    LLVMRustMetadataRef File,
     unsigned LineNo,
     unsigned ColumnNo)
 {
@@ -656,21 +726,11 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateTemplateTypeParameter(
       ));
 }
 
-extern "C" int64_t LLVMDIBuilderCreateOpDeref()
-{
-    return dwarf::DW_OP_deref;
-}
-
-extern "C" int64_t LLVMDIBuilderCreateOpPlus()
-{
-    return dwarf::DW_OP_plus;
-}
-
-extern "C" LLVMMetadataRef LLVMDIBuilderCreateNameSpace(
-    DIBuilderRef Builder,
-    LLVMMetadataRef Scope,
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateNameSpace(
+    LLVMRustDIBuilderRef Builder,
+    LLVMRustMetadataRef Scope,
     const char* Name,
-    LLVMMetadataRef File,
+    LLVMRustMetadataRef File,
     unsigned LineNo)
 {
     return wrap(Builder->createNameSpace(
@@ -680,22 +740,22 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateNameSpace(
         LineNo));
 }
 
-extern "C" void LLVMDICompositeTypeSetTypeArray(
-    DIBuilderRef Builder,
-    LLVMMetadataRef CompositeType,
-    LLVMMetadataRef TypeArray)
+extern "C" void LLVMRustDICompositeTypeSetTypeArray(
+    LLVMRustDIBuilderRef Builder,
+    LLVMRustMetadataRef CompositeType,
+    LLVMRustMetadataRef TypeArray)
 {
     DICompositeType *tmp = unwrapDI<DICompositeType>(CompositeType);
     Builder->replaceArrays(tmp, DINodeArray(unwrap<MDTuple>(TypeArray)));
 }
 
-extern "C" LLVMValueRef LLVMDIBuilderCreateDebugLocation(
+extern "C" LLVMValueRef LLVMRustDIBuilderCreateDebugLocation(
   LLVMContextRef Context,
   unsigned Line,
   unsigned Column,
-  LLVMMetadataRef Scope,
-  LLVMMetadataRef InlinedAt) {
-
+  LLVMRustMetadataRef Scope,
+  LLVMRustMetadataRef InlinedAt)
+{
     LLVMContext& context = *unwrap(Context);
 
     DebugLoc debug_loc = DebugLoc::get(Line,
@@ -706,12 +766,22 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateDebugLocation(
     return wrap(MetadataAsValue::get(context, debug_loc.getAsMDNode()));
 }
 
-extern "C" void LLVMWriteTypeToString(LLVMTypeRef Type, RustStringRef str) {
+extern "C" int64_t LLVMRustDIBuilderCreateOpDeref()
+{
+    return dwarf::DW_OP_deref;
+}
+
+extern "C" int64_t LLVMRustDIBuilderCreateOpPlus()
+{
+    return dwarf::DW_OP_plus;
+}
+
+extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Type, RustStringRef str) {
     raw_rust_string_ostream os(str);
     unwrap<llvm::Type>(Type)->print(os);
 }
 
-extern "C" void LLVMWriteValueToString(LLVMValueRef Value, RustStringRef str) {
+extern "C" void LLVMRustWriteValueToString(LLVMValueRef Value, RustStringRef str) {
     raw_rust_string_ostream os(str);
     os << "(";
     unwrap<llvm::Value>(Value)->getType()->print(os);
@@ -746,13 +816,6 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
     return true;
 }
 
-extern "C" void
-LLVMRustSetDLLStorageClass(LLVMValueRef Value,
-                           GlobalValue::DLLStorageClassTypes Class) {
-    GlobalValue *V = unwrap<GlobalValue>(Value);
-    V->setDLLStorageClass(Class);
-}
-
 // Note that the two following functions look quite similar to the
 // LLVMGetSectionName function. Sadly, it appears that this function only
 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
@@ -768,7 +831,7 @@ inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
     return reinterpret_cast<section_iterator*>(SI);
 }
 
-extern "C" int
+extern "C" size_t
 LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
     StringRef ret;
     if (std::error_code ec = (*unwrap(SI))->getName(ret))
@@ -787,13 +850,13 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef)
 
 extern "C" void
-LLVMWriteTwineToString(LLVMTwineRef T, RustStringRef str) {
+LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef str) {
     raw_rust_string_ostream os(str);
     unwrap(T)->print(os);
 }
 
 extern "C" void
-LLVMUnpackOptimizationDiagnostic(
+LLVMRustUnpackOptimizationDiagnostic(
     LLVMDiagnosticInfoRef di,
     const char **pass_name_out,
     LLVMValueRef *function_out,
@@ -811,7 +874,7 @@ LLVMUnpackOptimizationDiagnostic(
 }
 
 extern "C" void
-LLVMUnpackInlineAsmDiagnostic(
+LLVMRustUnpackInlineAsmDiagnostic(
     LLVMDiagnosticInfoRef di,
     unsigned *cookie_out,
     LLVMTwineRef *message_out,
@@ -826,17 +889,111 @@ LLVMUnpackInlineAsmDiagnostic(
     *instruction_out = wrap(ia->getInstruction());
 }
 
-extern "C" void LLVMWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) {
+extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) {
     raw_rust_string_ostream os(str);
     DiagnosticPrinterRawOStream dp(os);
     unwrap(di)->print(dp);
 }
 
-extern "C" int LLVMGetDiagInfoKind(LLVMDiagnosticInfoRef di) {
-    return unwrap(di)->getKind();
+enum class LLVMRustDiagnosticKind {
+    Other,
+    InlineAsm,
+    StackSize,
+    DebugMetadataVersion,
+    SampleProfile,
+    OptimizationRemark,
+    OptimizationRemarkMissed,
+    OptimizationRemarkAnalysis,
+    OptimizationRemarkAnalysisFPCommute,
+    OptimizationRemarkAnalysisAliasing,
+    OptimizationRemarkOther,
+    OptimizationFailure,
+};
+
+static LLVMRustDiagnosticKind
+to_rust(DiagnosticKind kind)
+{
+    switch (kind) {
+    case DK_InlineAsm:
+        return LLVMRustDiagnosticKind::InlineAsm;
+    case DK_StackSize:
+        return LLVMRustDiagnosticKind::StackSize;
+    case DK_DebugMetadataVersion:
+        return LLVMRustDiagnosticKind::DebugMetadataVersion;
+    case DK_SampleProfile:
+        return LLVMRustDiagnosticKind::SampleProfile;
+    case DK_OptimizationRemark:
+        return LLVMRustDiagnosticKind::OptimizationRemark;
+    case DK_OptimizationRemarkMissed:
+        return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
+    case DK_OptimizationRemarkAnalysis:
+        return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
+#if LLVM_VERSION_MINOR >= 8
+    case DK_OptimizationRemarkAnalysisFPCommute:
+        return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
+    case DK_OptimizationRemarkAnalysisAliasing:
+        return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
+#endif
+    default:
+#if LLVM_VERSION_MINOR >= 9
+        return (kind >= DK_FirstRemark && kind <= DK_LastRemark) ?
+            LLVMRustDiagnosticKind::OptimizationRemarkOther :
+            LLVMRustDiagnosticKind::Other;
+#else
+        return LLVMRustDiagnosticKind::Other;
+#endif
+  }
+}
+
+extern "C" LLVMRustDiagnosticKind LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef di) {
+    return to_rust((DiagnosticKind) unwrap(di)->getKind());
+}
+// This is kept distinct from LLVMGetTypeKind, because when
+// a new type kind is added, the Rust-side enum must be
+// updated or UB will result.
+extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
+  switch (unwrap(Ty)->getTypeID()) {
+  case Type::VoidTyID:
+    return LLVMVoidTypeKind;
+  case Type::HalfTyID:
+    return LLVMHalfTypeKind;
+  case Type::FloatTyID:
+    return LLVMFloatTypeKind;
+  case Type::DoubleTyID:
+    return LLVMDoubleTypeKind;
+  case Type::X86_FP80TyID:
+    return LLVMX86_FP80TypeKind;
+  case Type::FP128TyID:
+    return LLVMFP128TypeKind;
+  case Type::PPC_FP128TyID:
+    return LLVMPPC_FP128TypeKind;
+  case Type::LabelTyID:
+    return LLVMLabelTypeKind;
+  case Type::MetadataTyID:
+    return LLVMMetadataTypeKind;
+  case Type::IntegerTyID:
+    return LLVMIntegerTypeKind;
+  case Type::FunctionTyID:
+    return LLVMFunctionTypeKind;
+  case Type::StructTyID:
+    return LLVMStructTypeKind;
+  case Type::ArrayTyID:
+    return LLVMArrayTypeKind;
+  case Type::PointerTyID:
+    return LLVMPointerTypeKind;
+  case Type::VectorTyID:
+    return LLVMVectorTypeKind;
+  case Type::X86_MMXTyID:
+    return LLVMX86_MMXTypeKind;
+#if LLVM_VERSION_MINOR >= 8
+  case Type::TokenTyID:
+    return LLVMTokenTypeKind;
+#endif
+  }
+  llvm_unreachable("Unhandled TypeID.");
 }
 
-extern "C" void LLVMWriteDebugLocToString(
+extern "C" void LLVMRustWriteDebugLocToString(
     LLVMContextRef C,
     LLVMDebugLocRef dl,
     RustStringRef str)
@@ -847,7 +1004,7 @@ extern "C" void LLVMWriteDebugLocToString(
 
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
 
-extern "C" void LLVMSetInlineAsmDiagnosticHandler(
+extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
     LLVMContextRef C,
     LLVMContext::InlineAsmDiagHandlerTy H,
     void *CX)
@@ -855,7 +1012,8 @@ extern "C" void LLVMSetInlineAsmDiagnosticHandler(
     unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
 }
 
-extern "C" void LLVMWriteSMDiagnosticToString(LLVMSMDiagnosticRef d, RustStringRef str) {
+extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef d,
+                                                 RustStringRef str) {
     raw_rust_string_ostream os(str);
     unwrap(d)->print("", os);
 }
index 2a47e8b089549a77bc20b0761c835adb953505a2..5aae11fb456b6d9ce0abb96efcf587c9fbfec24f 100644 (file)
 
 void LLVMRustSetLastError(const char*);
 
+enum class LLVMRustResult {
+    Success,
+    Failure
+};
+
 typedef struct OpaqueRustString *RustStringRef;
 typedef struct LLVMOpaqueTwine *LLVMTwineRef;
 typedef struct LLVMOpaqueDebugLoc *LLVMDebugLocRef;
index 9ae9e795466d28a65554944e7d8a87a5ba669278..8a666168c86fd22207a7067c426fe0c89329dfd6 100644 (file)
@@ -11,5 +11,6 @@
 #![feature(box_syntax)]
 
 const CON : Box<i32> = box 0; //~ ERROR E0010
+                              //~| NOTE allocation not allowed in
 
 fn main() {}
index b2f20442b77ad4a116c65497cd6675b664e189ed..ca496a24701fba48141189c332229ad1248707e5 100644 (file)
@@ -17,6 +17,8 @@ fn main() {
     let d = Dog { name: "Rusty".to_string(), age: 8 };
 
     match d {
-        Dog { age: x } => {} //~ ERROR E0027
+        Dog { age: x } => {}
+        //~^ ERROR pattern does not mention field `name`
+        //~| NOTE missing field `name`
     }
 }
index 9cbdec9952053ad51affc0d47fe17cdce3a8eaa2..ec84e2a3f8a3650c8e910752e5fdeba1fb71a4fc 100644 (file)
@@ -12,7 +12,11 @@ fn main() {
     let s = "hoho";
 
     match s {
-        "hello" ... "world" => {} //~ ERROR E0029
+        "hello" ... "world" => {}
+        //~^ ERROR only char and numeric types are allowed in range patterns
+        //~| NOTE ranges require char or numeric types
+        //~| NOTE start type: &'static str
+        //~| NOTE end type: &'static str
         _ => {}
     }
 }
index f998778a50d66b0cf8fab95bdc60c9410fa1e097..80ff57c36359561f28aac3410823d551f6afe16e 100644 (file)
@@ -20,5 +20,7 @@ fn drop(&mut self) {
 
 fn main() {
     let mut x = Foo { x: -7 };
-    x.drop(); //~ ERROR E0040
+    x.drop();
+    //~^ ERROR E0040
+    //~| NOTE call to destructor method
 }
index 63bd0a5ca285826a84c5458c37845d4fa215bc3c..a8b56b2b9ab37248a596f3f37df0d5e15290ff34 100644 (file)
@@ -14,7 +14,9 @@ trait Foo {
 
 struct Bar;
 
-impl Foo for Bar {} //~ ERROR E0046
+impl Foo for Bar {}
+//~^ ERROR E0046
+//~| NOTE missing `foo` in implementation
 
 fn main() {
 }
index f86d7ec114b938132fd532a8bc61a08b538b7872..2b2d278ad4cc63eb6f93cb47ecc215e3557d38ce 100644 (file)
@@ -18,5 +18,7 @@ fn foo(&self) {}
 fn main() {
     let foo = Foo;
     let ref_foo = &&Foo;
-    ref_foo.foo(); //~ ERROR E0055
+    ref_foo.foo();
+    //~^ ERROR E0055
+    //~| NOTE deref recursion limit reached
 }
index b4a289874979206a59f328f4e05607d41d445902..e1f2618c180f6d54db60ae488094f0a166e15e87 100644 (file)
@@ -13,5 +13,8 @@
 }
 
 fn main() {
-    unsafe { printf(); } //~ ERROR E0060
+    unsafe { printf(); }
+    //~^ ERROR E0060
+    //~| NOTE expected at least 1 parameter
+    //~| NOTE the following parameter type was expected
 }
index 4a8eac2a9e2268d98e85dda3b9d6cb13d4edb998..ca04b059dc7f699cc0a576378b0ac94252a10d90 100644 (file)
@@ -11,5 +11,8 @@
 fn f(a: u16, b: &str) {}
 
 fn main() {
-    f(0); //~ ERROR E0061
+    f(0);
+    //~^ ERROR E0061
+    //~| NOTE expected 2 parameters
+    //~| NOTE the following parameter types were expected
 }
index 86ec7db14b5c17d50621bddb8b45bf289ec56647..822d93e52d588c5688a7ecc759dd023b9ee5cf1d 100644 (file)
@@ -14,7 +14,9 @@ struct Foo {
 
 fn main() {
     let x = Foo {
+        x: 0, //~ NOTE first use of `x`
         x: 0,
-        x: 0, //~ ERROR E0062
+        //~^ ERROR E0062
+        //~| NOTE used more than once
     };
 }
index d164d86348784255b86e9bf57dd5efb746eb1de7..00facc91728027608eb85702b2517cd21e561ca1 100644 (file)
@@ -9,7 +9,9 @@
 // except according to those terms.
 
 fn foo() -> u8 {
-    return; //~ ERROR E0069
+    return;
+    //~^ ERROR `return;` in a function whose return type is not `()`
+    //~| NOTE return type is not ()
 }
 
 fn main() {
index 658c8fb1551149fd909d0464a66fd109795eb006..6f0e55efffc921dc31a991972b007f515b5f46de 100644 (file)
 enum Foo { FirstValue(i32) }
 
 fn main() {
-    let u = Foo::FirstValue { value: 0 }; //~ ERROR E0071
-    let t = u32 { value: 4 }; //~ ERROR E0071
+    let u = Foo::FirstValue { value: 0 };
+    //~^ ERROR `Foo::FirstValue` does not name a struct or a struct variant [E0071]
+    //~| NOTE not a struct
+
+    let t = u32 { value: 4 };
+    //~^ ERROR `u32` does not name a struct or a struct variant [E0071]
+    //~| NOTE not a struct
 }
index 23957c72ff00eadd4ab402b8c0717bb947b11eb4..c9b7f549d5aaaea6cf029292716f1541c9b0d31d 100644 (file)
@@ -10,6 +10,7 @@
 
 enum Foo {
     Q = "32" //~ ERROR E0079
+    //~^ expected 'isize' type
 }
 
 fn main() {
index 7651626d44f859f44e9b5fdf4320a733c10c9487..0005da048e4a5706fb37ebed9292f51b3902f04d 100644 (file)
@@ -9,5 +9,7 @@
 // except according to those terms.
 
 fn main() {
-    let x = |_| {}; //~ ERROR E0101
+    let x = |_| {};
+    //~^ ERROR E0101
+    //~| NOTE cannot resolve type of expression
 }
index c4ddbab3e861a2034ad8f36e1a047c59195db179..1d64798bb838202e6f1696addb1f96adaab34a7a 100644 (file)
@@ -9,5 +9,7 @@
 // except according to those terms.
 
 fn main() {
-    let x = []; //~ ERROR E0102
+    let x = [];
+    //~^ ERROR E0102
+    //~| NOTE cannot resolve type of variable
 }
index f1cd530863d341e4e291856688ed9cb7652d032d..dab03f0bccfd0b88befcaa5d581470af50a530a1 100644 (file)
@@ -9,13 +9,19 @@
 // except according to those terms.
 
 struct Foo {
-    x: &bool, //~ ERROR E0106
+    x: &bool,
+    //~^ ERROR E0106
+    //~| NOTE expected lifetime parameter
 }
 enum Bar {
     A(u8),
-    B(&bool), //~ ERROR E0106
+    B(&bool),
+   //~^ ERROR E0106
+   //~| NOTE expected lifetime parameter
 }
-type MyStr = &str; //~ ERROR E0106
+type MyStr = &str;
+        //~^ ERROR E0106
+        //~| NOTE expected lifetime parameter
 
 fn main() {
 }
index d27b70865bbfbccd7c925e6c03f1004f7de707bf..5f333e17c478efeabaeec150842e1bd4530df4ff 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 struct Foo<'a>(&'a str);
+struct Buzz<'a, 'b>(&'a str, &'b str);
 
 enum Bar {
     A,
@@ -16,9 +17,19 @@ enum Bar {
     C,
 }
 
-struct Baz<'a> {
-    foo: Foo, //~ ERROR E0107
-    bar: Bar<'a>, //~ ERROR E0107
+struct Baz<'a, 'b, 'c> {
+    foo: Foo,
+    //~^ ERROR E0107
+    //~| expected 1 lifetime parameter
+    buzz: Buzz<'a>,
+    //~^ ERROR E0107
+    //~| expected 2 lifetime parameters
+    bar: Bar<'a>,
+    //~^ ERROR E0107
+    //~| unexpected lifetime parameter
+    foo2: Foo<'a, 'b, 'c>,
+    //~^ ERROR E0107
+    //~| 2 unexpected lifetime parameters
 }
 
 fn main() {
index 9fc478422504bbe750c2f3b230f022bdb56c61cc..2e4cbf8692693c6844a318a924eba6bae0bb8c3e 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 type X = u32<i32>; //~ ERROR E0109
+                   //~| NOTE type parameter not allowed
 
 fn main() {
 }
index fd169f4acc5eb0250ad5fae39283d51883764ee0..5a9e7a43de96b6b68142936404135d419937ba01 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 type X = u32<'static>; //~ ERROR E0110
+                       //~| NOTE lifetime parameter not allowed on this type
 
 fn main() {
 }
index 4020aa9475aaa3273ac0170565a91ff19d4c233e..f885241eec4c7f1b00a7451fa11d091afb60fc95 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-impl Vec<u8> {} //~ ERROR E0116
+impl Vec<u8> {}
+//~^ ERROR E0116
+//~| NOTE impl for type defined outside of crate.
+//~| NOTE define and implement a trait or new type instead
 
 fn main() {
 }
index 16d713bba92ab3c11b0f848d0c22a16268efc708..e9375e673253fb863edb4135df4256446645d4ec 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 impl Drop for u32 {} //~ ERROR E0117
+//~^ NOTE impl doesn't use types inside crate
+//~| NOTE the impl does not reference any types defined in this crate
 
 fn main() {
 }
index d37ff34b861f41d272970920bf135f222773d5ff..3fc478f1e403e3adf57ed00c48e547b1c1f1dfbb 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 impl (u8, u8) { //~ ERROR E0118
+//~^ NOTE impl requires a base type
+//~| NOTE either implement a trait on it or create a newtype to wrap it instead
     fn get_state(&self) -> String {
         String::new()
     }
index 9528631b3047b6bd749b3aad2db3a7f1ea5cd4a0..56820bcd1840ceafae7c0c45bab2322aa53ac2e4 100644 (file)
@@ -12,7 +12,7 @@ trait MyTrait {
     fn get(&self) -> usize;
 }
 
-impl<T> MyTrait for T {
+impl<T> MyTrait for T { //~ NOTE first implementation here
     fn get(&self) -> usize { 0 }
 }
 
@@ -21,6 +21,7 @@ struct Foo {
 }
 
 impl MyTrait for Foo { //~ ERROR E0119
+                       //~| NOTE conflicting implementation for `Foo`
     fn get(&self) -> usize { self.value }
 }
 
index de084274f6fb80883c8cce0380e1d4cf5cba7d1f..3fdeb7531754021d2f7ae780f039fb672df6265d 100644 (file)
@@ -10,7 +10,9 @@
 
 trait MyTrait {}
 
-impl Drop for MyTrait { //~ ERROR E0120
+impl Drop for MyTrait {
+              //~^ ERROR E0120
+              //~| NOTE implementing Drop requires a struct
     fn drop(&mut self) {}
 }
 
index 414b19ead624d052aea6d42f382d0b27b963fe5a..18c507461065642ab97ae52c82e48b5d116dc691 100644 (file)
@@ -9,8 +9,10 @@
 // except according to those terms.
 
 struct Foo {
+    field1: i32, //~ NOTE `field1` first declared here
     field1: i32,
-    field1: i32, //~ ERROR E0124
+    //~^ ERROR field `field1` is already declared [E0124]
+    //~| NOTE field already declared
 }
 
 fn main() {
index aa11577ccdf1ed1f1a0578dcfd050079d1b2c7ac..e6e924e2d966fd9cc8a335060afe22098ed44b7a 100644 (file)
@@ -8,5 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn main<T>() { //~ ERROR E0131
+fn main<T>() {
+    //~^ ERROR E0131
+    //~| NOTE main cannot have type parameters
 }
index ff19a577f903dbe4016e18043eb6943768c6fb97..1a33fb24ca1a1a0eee3d3dac51f6620ffc602910 100644 (file)
@@ -12,6 +12,7 @@
 
 #[start]
 fn f<T>() {} //~ ERROR E0132
+             //~| NOTE start function cannot have type parameters
 
 fn main() {
 }
index 695ce7995a9a46ef3cb44fad2b4a5cc687c8388d..f45afc9f37bd51f0cb816552f5305e0c9a58af31 100644 (file)
@@ -11,7 +11,9 @@
 #![feature(main)]
 
 #[main]
-fn foo() {}
+fn foo() {} //~ NOTE first #[main] function
 
 #[main]
-fn f() {} //~ ERROR E0137
+fn f() {}
+//~^ ERROR E0137
+//~| NOTE additional #[main] function
index 9fa41249aa50b06a78d8286e4963c8ababc4f31f..f8585d71b402a080c052a5d09a79a45542b5079f 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn foo() -> ! { return; } //~ ERROR E0166
+fn foo() -> ! { return; }
+    //~^ ERROR E0166
+    //~| NOTE diverging function cannot return
 
 fn main() {
 }
index 7011bf0e93734f9a4220b17c9a5a66ccfcfbca47..485a31d96663795a2cbb2eabe73d3ede755fde00 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn foo(bar: i32+std::fmt::Display) {} //~ ERROR E0172
+fn foo(bar: i32+std::fmt::Display) {}
+    //~^ ERROR E0172
+    //~| NOTE expected a trait
 
 fn main() {
 }
index f34f3834e05b196d47fd5715dfdc159745a5df1b..6527465e0b7f74631c17a159fe5ca41f289b9cbb 100644 (file)
 trait Foo {}
 
 struct Bar<'a> {
-    w: &'a Foo + Copy, //~ ERROR E0178
-    x: &'a Foo + 'a, //~ ERROR E0178
-    y: &'a mut Foo + 'a, //~ ERROR E0178
-    z: fn() -> Foo + 'a, //~ ERROR E0178
+    w: &'a Foo + Copy,
+    //~^ ERROR E0178
+    //~| NOTE expected a path
+    x: &'a Foo + 'a,
+    //~^ ERROR E0178
+    //~| NOTE expected a path
+    y: &'a mut Foo + 'a,
+    //~^ ERROR E0178
+    //~| NOTE expected a path
+    z: fn() -> Foo + 'a,
+    //~^ ERROR E0178
+    //~| NOTE expected a path
 }
 
 fn main() {
index 0e33687a84dfb6857fae8f563c874600bc434f73..be54c3754ea1fe98e7aef7f4aaef686d8282f629 100644 (file)
@@ -9,13 +9,14 @@
 // except according to those terms.
 
 trait Foo {
-    fn foo();
+    fn foo(); //~ trait declared without `&self`
 }
 
 struct Bar;
 
 impl Foo for Bar {
     fn foo(&self) {} //~ ERROR E0185
+    //~^ `&self` used in impl
 }
 
 fn main() {
index aa0a38bedcb543e932123f4bb59d0798c6658a19..55a3490cac4a620b9206e243cd81687e084edb8d 100644 (file)
@@ -9,13 +9,14 @@
 // except according to those terms.
 
 trait Foo {
-    fn foo(&self);
+    fn foo(&self); //~ `&self` used in trait
 }
 
 struct Bar;
 
 impl Foo for Bar {
     fn foo() {} //~ ERROR E0186
+    //~^ expected `&self` in impl
 }
 
 fn main() {
diff --git a/src/test/compile-fail/E0201.rs b/src/test/compile-fail/E0201.rs
new file mode 100644 (file)
index 0000000..ff6cb55
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo(u8);
+
+impl Foo {
+    fn bar(&self) -> bool { self.0 > 5 }
+    fn bar() {} //~ ERROR E0201
+}
+
+trait Baz {
+    type Quux;
+    fn baz(&self) -> bool;
+}
+
+impl Baz for Foo {
+    type Quux = u32;
+
+    fn baz(&self) -> bool { true }
+    fn baz(&self) -> bool { self.0 > 5 } //~ ERROR E0201
+    type Quux = u32; //~ ERROR E0201
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/E0204.rs b/src/test/compile-fail/E0204.rs
new file mode 100644 (file)
index 0000000..0f108a1
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo {
+    foo: Vec<u32>,
+}
+
+impl Copy for Foo { }
+//~^ ERROR E0204
+//~| NOTE field `foo` does not implement `Copy`
+
+#[derive(Copy)]
+//~^ ERROR E0204
+//~| NOTE field `ty` does not implement `Copy`
+//~| NOTE in this expansion of #[derive(Copy)]
+struct Foo2<'a> {
+    ty: &'a mut bool,
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/E0205.rs b/src/test/compile-fail/E0205.rs
new file mode 100644 (file)
index 0000000..37ac57a
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+enum Foo {
+    Bar(Vec<u32>),
+    Baz,
+}
+
+impl Copy for Foo { }
+//~^ ERROR E0205
+//~| NOTE variant `Bar` does not implement `Copy`
+
+#[derive(Copy)]
+//~^ ERROR E0205
+//~| NOTE variant `Bar` does not implement `Copy`
+//~| NOTE in this expansion of #[derive(Copy)]
+enum Foo2<'a> {
+    Bar(&'a mut bool),
+    Baz,
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/E0206.rs b/src/test/compile-fail/E0206.rs
new file mode 100644 (file)
index 0000000..888e42e
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+type Foo = i32;
+
+impl Copy for Foo { }
+//~^ ERROR the trait `Copy` may not be implemented for this type
+//~| NOTE type is not a structure or enumeration
+//~| ERROR only traits defined in the current crate can be implemented for arbitrary types
+//~| NOTE impl doesn't use types inside crate
+//~| NOTE the impl does not reference any types defined in this crate
+
+#[derive(Copy, Clone)]
+struct Bar;
+
+impl Copy for &'static Bar { }
+//~^ ERROR the trait `Copy` may not be implemented for this type
+//~| NOTE type is not a structure or enumeration
+
+fn main() {
+}
diff --git a/src/test/compile-fail/E0207.rs b/src/test/compile-fail/E0207.rs
new file mode 100644 (file)
index 0000000..43ff085
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo;
+
+impl<T: Default> Foo { //~ ERROR E0207
+                       //~| NOTE unconstrained lifetime parameter
+    fn get(&self) -> T {
+        <T as Default>::default()
+    }
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/E0214.rs b/src/test/compile-fail/E0214.rs
new file mode 100644 (file)
index 0000000..5960934
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let v: Vec(&str) = vec!["foo"]; //~ ERROR E0214
+}
diff --git a/src/test/compile-fail/E0220.rs b/src/test/compile-fail/E0220.rs
new file mode 100644 (file)
index 0000000..17e2b18
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Trait {
+    type Bar;
+}
+
+type Foo = Trait<F=i32>; //~ ERROR E0220
+                         //~^ ERROR E0191
+
+fn main() {
+}
diff --git a/src/test/compile-fail/E0221.rs b/src/test/compile-fail/E0221.rs
new file mode 100644 (file)
index 0000000..213ec5a
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait T1 {}
+trait T2 {}
+
+trait Foo {
+    type A: T1;
+}
+
+trait Bar : Foo {
+    type A: T2;
+    fn do_something() {
+        let _: Self::A; //~ ERROR E0221
+    }
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/E0223.rs b/src/test/compile-fail/E0223.rs
new file mode 100644 (file)
index 0000000..56057b3
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait MyTrait { type X; }
+
+fn main() {
+    let foo: MyTrait::X;
+    //~^ ERROR ambiguous associated type
+    //~| NOTE ambiguous associated type
+    //~| NOTE specify the type using the syntax `<Type as MyTrait>::X`
+}
diff --git a/src/test/compile-fail/E0225.rs b/src/test/compile-fail/E0225.rs
new file mode 100644 (file)
index 0000000..b013788
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let _: Box<std::io::Read + std::io::Write>;
+    //~^ ERROR only the builtin traits can be used as closure or object bounds [E0225]
+    //~| NOTE non-builtin trait used as bounds
+}
diff --git a/src/test/compile-fail/E0229.rs b/src/test/compile-fail/E0229.rs
new file mode 100644 (file)
index 0000000..6ff0bae
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub trait Foo {
+    type A;
+    fn boo(&self) -> <Self as Foo>::A;
+}
+
+struct Bar;
+
+impl Foo for isize {
+    type A = usize;
+    fn boo(&self) -> usize { 42 }
+}
+
+fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
+//~^ ERROR associated type bindings are not allowed here [E0229]
+//~| NOTE associate type not allowed here
+
+fn main() {
+}
diff --git a/src/test/compile-fail/E0232.rs b/src/test/compile-fail/E0232.rs
new file mode 100644 (file)
index 0000000..efeb869
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(on_unimplemented)]
+
+#[rustc_on_unimplemented] //~ ERROR E0232
+trait Bar {}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/E0243.rs b/src/test/compile-fail/E0243.rs
new file mode 100644 (file)
index 0000000..77c9856
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo<T> { x: T }
+struct Bar { x: Foo }
+                //~^ ERROR E0243
+                //~| NOTE expected 1 type arguments, found 0
+
+fn main() {
+}
diff --git a/src/test/compile-fail/E0244.rs b/src/test/compile-fail/E0244.rs
new file mode 100644 (file)
index 0000000..5678a7f
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo { x: bool }
+struct Bar<S, T> { x: Foo<S, T> }
+                      //~^ ERROR E0244
+                      //~| NOTE expected no type arguments, found 2
+
+
+fn main() {
+}
diff --git a/src/test/compile-fail/E0248.rs b/src/test/compile-fail/E0248.rs
new file mode 100644 (file)
index 0000000..fdfd41a
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+enum Foo {
+    Bar(u32),
+}
+
+fn do_something(x: Foo::Bar) { } //~ ERROR E0248
+
+fn main() {
+}
diff --git a/src/test/compile-fail/E0252.rs b/src/test/compile-fail/E0252.rs
new file mode 100644 (file)
index 0000000..6b353c8
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use foo::baz;
+use bar::baz; //~ ERROR E0252
+
+mod foo {
+    pub struct baz;
+}
+
+mod bar {
+    pub mod baz {}
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/E0253.rs b/src/test/compile-fail/E0253.rs
new file mode 100644 (file)
index 0000000..28fcf44
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod foo {
+    pub trait MyTrait {
+        fn do_something();
+    }
+}
+
+use foo::MyTrait::do_something; //~ ERROR E0253
+
+fn main() {}
diff --git a/src/test/compile-fail/E0254.rs b/src/test/compile-fail/E0254.rs
new file mode 100644 (file)
index 0000000..28f9aea
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate collections;
+
+mod foo {
+    pub trait collections {
+        fn do_something();
+    }
+}
+
+use foo::collections; //~ ERROR E0254
+
+fn main() {}
diff --git a/src/test/compile-fail/E0255.rs b/src/test/compile-fail/E0255.rs
new file mode 100644 (file)
index 0000000..e05c6be
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use bar::foo;
+
+fn foo() {} //~ ERROR E0255
+
+mod bar {
+     pub fn foo() {}
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/E0259.rs b/src/test/compile-fail/E0259.rs
new file mode 100644 (file)
index 0000000..6b7e861
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate collections;
+extern crate libc as collections; //~ ERROR E0259
+
+fn main() {}
diff --git a/src/test/compile-fail/E0260.rs b/src/test/compile-fail/E0260.rs
new file mode 100644 (file)
index 0000000..d20829b
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate collections;
+
+mod collections { //~ ERROR E0260
+    pub trait MyTrait {
+        fn do_something();
+    }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/E0261.rs b/src/test/compile-fail/E0261.rs
new file mode 100644 (file)
index 0000000..4196ad3
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn foo(x: &'a str) { } //~ ERROR E0261
+
+struct Foo {
+    x: &'a str, //~ ERROR E0261
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/E0262.rs b/src/test/compile-fail/E0262.rs
new file mode 100644 (file)
index 0000000..e09e476
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn foo<'static>(x: &'static str) { } //~ ERROR E0262
+
+fn main() {}
diff --git a/src/test/compile-fail/E0263.rs b/src/test/compile-fail/E0263.rs
new file mode 100644 (file)
index 0000000..09f654c
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { } //~ ERROR E0263
+
+fn main() {}
diff --git a/src/test/compile-fail/E0264.rs b/src/test/compile-fail/E0264.rs
new file mode 100644 (file)
index 0000000..9233297
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(lang_items)]
+
+extern "C" {
+    #[lang = "cake"]
+    fn cake(); //~ ERROR E0264
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/E0267.rs b/src/test/compile-fail/E0267.rs
new file mode 100644 (file)
index 0000000..6287256
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let w = || { break; }; //~ ERROR E0267
+}
diff --git a/src/test/compile-fail/E0268.rs b/src/test/compile-fail/E0268.rs
new file mode 100644 (file)
index 0000000..41e88e2
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    break; //~ ERROR E0268
+}
diff --git a/src/test/compile-fail/E0271.rs b/src/test/compile-fail/E0271.rs
new file mode 100644 (file)
index 0000000..d322c8b
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Trait { type AssociatedType; }
+
+fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
+    println!("in foo");
+}
+
+impl Trait for i8 { type AssociatedType = &'static str; }
+
+fn main() {
+    foo(3_i8); //~ ERROR E0271
+}
diff --git a/src/test/compile-fail/E0275.rs b/src/test/compile-fail/E0275.rs
new file mode 100644 (file)
index 0000000..8dfd1d9
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Foo {}
+
+struct Bar<T>(T);
+
+impl<T> Foo for T where Bar<T>: Foo {} //~ ERROR E0275
+
+fn main() {
+}
diff --git a/src/test/compile-fail/E0276.rs b/src/test/compile-fail/E0276.rs
new file mode 100644 (file)
index 0000000..62e43b0
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Foo {
+    fn foo<T>(x: T);
+}
+
+impl Foo for bool {
+    fn foo<T>(x: T) where T: Copy {} //~ ERROR E0276
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/E0277.rs b/src/test/compile-fail/E0277.rs
new file mode 100644 (file)
index 0000000..7737f12
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Foo {
+    fn bar(&self);
+}
+
+fn some_func<T: Foo>(foo: T) {
+    foo.bar();
+}
+
+fn main() {
+    some_func(5i32); //~ ERROR E0277
+}
diff --git a/src/test/compile-fail/E0281.rs b/src/test/compile-fail/E0281.rs
new file mode 100644 (file)
index 0000000..d468cd3
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn foo<F: Fn()>(x: F) { }
+
+fn main() {
+    foo(|y| { }); //~ ERROR E0281
+                  //~^ ERROR E0281
+}
diff --git a/src/test/compile-fail/E0282.rs b/src/test/compile-fail/E0282.rs
new file mode 100644 (file)
index 0000000..dfc7026
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let x = "hello".chars().rev().collect(); //~ ERROR E0282
+}
diff --git a/src/test/compile-fail/E0283.rs b/src/test/compile-fail/E0283.rs
new file mode 100644 (file)
index 0000000..844c47f
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Generator {
+    fn create() -> u32;
+}
+
+struct Impl;
+
+impl Generator for Impl {
+    fn create() -> u32 { 1 }
+}
+
+struct AnotherImpl;
+
+impl Generator for AnotherImpl {
+    fn create() -> u32 { 2 }
+}
+
+fn main() {
+    let cont: u32 = Generator::create(); //~ ERROR E0283
+}
diff --git a/src/test/compile-fail/E0296.rs b/src/test/compile-fail/E0296.rs
new file mode 100644 (file)
index 0000000..562fd00
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![recursion_limit] //~ ERROR E0296
+
+fn main() {}
diff --git a/src/test/compile-fail/E0297.rs b/src/test/compile-fail/E0297.rs
new file mode 100644 (file)
index 0000000..43166c1
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let xs : Vec<Option<i32>> = vec!(Some(1), None);
+
+    for Some(x) in xs {} //~ ERROR E0297
+}
diff --git a/src/test/compile-fail/E0301.rs b/src/test/compile-fail/E0301.rs
new file mode 100644 (file)
index 0000000..06e9828
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    match Some(()) {
+        None => { },
+        option if option.take().is_none() => {}, //~ ERROR E0301
+        Some(_) => { }
+    }
+}
diff --git a/src/test/compile-fail/E0302.rs b/src/test/compile-fail/E0302.rs
new file mode 100644 (file)
index 0000000..6a5ad40
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    match Some(()) {
+        None => { },
+        option if { option = None; false } => { }, //~ ERROR E0302
+        Some(_) => { }
+    }
+}
diff --git a/src/test/compile-fail/E0303.rs b/src/test/compile-fail/E0303.rs
new file mode 100644 (file)
index 0000000..67947fd
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    match Some("hi".to_string()) {
+        ref op_string_ref @ Some(s) => {}, //~ ERROR E0303
+                                           //~^ ERROR E0009
+        None => {},
+    }
+}
diff --git a/src/test/compile-fail/E0306.rs b/src/test/compile-fail/E0306.rs
new file mode 100644 (file)
index 0000000..9ffaef7
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const A: [u32; "hello"] = [];
+//~^ ERROR expected `usize` for array length, found string literal [E0306]
+//~| NOTE expected `usize`
+
+const B: [u32; true] = [];
+//~^ ERROR expected `usize` for array length, found boolean [E0306]
+//~| NOTE expected `usize`
+
+const C: [u32; 0.0] = [];
+//~^ ERROR expected `usize` for array length, found float [E0306]
+//~| NOTE expected `usize`
+
+fn main() {
+}
diff --git a/src/test/compile-fail/E0308-2.rs b/src/test/compile-fail/E0308-2.rs
new file mode 100644 (file)
index 0000000..8c9fc95
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::rc::Rc;
+
+struct Foo;
+
+impl Foo {
+    fn x(self: Rc<Foo>) {} //~ ERROR E0308
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/E0308-3.rs b/src/test/compile-fail/E0308-3.rs
new file mode 100644 (file)
index 0000000..d7dca05
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() -> i32 { 0 } //~ ERROR E0308
diff --git a/src/test/compile-fail/E0308-4.rs b/src/test/compile-fail/E0308-4.rs
new file mode 100644 (file)
index 0000000..bb4cd14
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let x = 1u8;
+    match x {
+        0u8...3i8 => (), //~ ERROR E0308
+        _ => ()
+    }
+}
diff --git a/src/test/compile-fail/E0308.rs b/src/test/compile-fail/E0308.rs
new file mode 100644 (file)
index 0000000..078f1d3
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(intrinsics)]
+
+extern "rust-intrinsic" {
+    fn size_of<T>(); //~ ERROR E0308
+}
+
+fn main() {
+}
index becbc27138b770e700d524844357252c7c017c95..ff886e63dc59ef1aebab668fe16ce51d5edcd29c 100644 (file)
@@ -15,15 +15,21 @@ trait Get {
 
 fn get<T:Get,U:Get>(x: T, y: U) -> Get::Value {}
 //~^ ERROR ambiguous associated type
+//~| NOTE ambiguous associated type
+//~| NOTE specify the type using the syntax `<Type as Get>::Value`
 
 trait Grab {
     type Value;
     fn grab(&self) -> Grab::Value;
     //~^ ERROR ambiguous associated type
+    //~| NOTE ambiguous associated type
+    //~| NOTE specify the type using the syntax `<Type as Grab>::Value`
 }
 
 type X = std::ops::Deref::Target;
 //~^ ERROR ambiguous associated type
+//~| NOTE ambiguous associated type
+//~| NOTE specify the type using the syntax `<Type as std::ops::Deref>::Target`
 
 fn main() {
 }
index de315a41361a7900667705cb9eb7882a7c871548..1a5496f0551507354ffcb5219f7fbca94911b742 100644 (file)
@@ -11,7 +11,9 @@
 // Tests that a function with a ! annotation always actually fails
 
 fn bad_bang(i: usize) -> ! {
-    return 7; //~ ERROR `return` in a function declared as diverging [E0166]
+    return 7;
+    //~^ ERROR `return` in a function declared as diverging [E0166]
+    //~| NOTE diverging function cannot return
 }
 
 fn main() { bad_bang(5); }
index 87e40df7663baacabd7c522321104fc0e7c82a61..ec330247f238b07c77a7f6a6b955dcaced8651b0 100644 (file)
@@ -22,4 +22,6 @@ fn main() {
     let mut books = vec![1,2,3];
     spawn(|| books.push(4));
     //~^ ERROR E0373
+    //~| NOTE `books` is borrowed here
+    //~| NOTE may outlive borrowed value `books`
 }
index 67700be890b1faa8a9c9090fdb0ea8382ddfd854..81685c32f2f29b6285b5fdadd05532746cc4c5b0 100644 (file)
@@ -20,6 +20,8 @@ fn foo<'a>(x: &'a i32) -> Box<FnMut()+'a> {
     let mut books = vec![1,2,3];
     Box::new(|| books.push(4))
     //~^ ERROR E0373
+    //~| NOTE `books` is borrowed here
+    //~| NOTE may outlive borrowed value `books`
 }
 
 fn main() { }
index 9c210c132a3131084733aead1eabdf7b34870d8c..f686a146042cee4351a2c1874605d7a3ab7e000a 100644 (file)
@@ -27,23 +27,34 @@ impl Clone for TestE { fn clone(&self) -> Self { *self } }
 impl Copy for MyType {}
 
 impl Copy for &'static mut MyType {}
-//~^ ERROR E0206
+//~^ ERROR the trait `Copy` may not be implemented for this type
+//~| NOTE type is not a structure or enumeration
 impl Clone for MyType { fn clone(&self) -> Self { *self } }
 
 impl Copy for (MyType, MyType) {}
-//~^ ERROR E0206
-//~| ERROR E0117
+//~^ ERROR the trait `Copy` may not be implemented for this type
+//~| NOTE type is not a structure or enumeration
+//~| ERROR only traits defined in the current crate can be implemented for arbitrary types
+//~| NOTE impl doesn't use types inside crate
+//~| NOTE the impl does not reference any types defined in this crate
 
 impl Copy for &'static NotSync {}
-//~^ ERROR E0206
+//~^ ERROR the trait `Copy` may not be implemented for this type
+//~| NOTE type is not a structure or enumeration
 
 impl Copy for [MyType] {}
-//~^ ERROR E0206
-//~| ERROR E0117
+//~^ ERROR the trait `Copy` may not be implemented for this type
+//~| NOTE type is not a structure or enumeration
+//~| ERROR only traits defined in the current crate can be implemented for arbitrary types
+//~| NOTE impl doesn't use types inside crate
+//~| NOTE the impl does not reference any types defined in this crate
 
 impl Copy for &'static [NotSync] {}
-//~^ ERROR E0206
-//~| ERROR E0117
+//~^ ERROR the trait `Copy` may not be implemented for this type
+//~| NOTE type is not a structure or enumeration
+//~| ERROR only traits defined in the current crate can be implemented for arbitrary types
+//~| NOTE impl doesn't use types inside crate
+//~| NOTE the impl does not reference any types defined in this crate
 
 fn main() {
 }
index f666140970b6e125b0d27f0740c15dfdbfbe1ca2..42fb40394fb298bf7c19bb067019e5d8db716adb 100644 (file)
 #![feature(const_indexing)]
 #![deny(const_err)]
 
-pub const A: i8 = -std::i8::MIN; //~ ERROR attempted to negate with overflow
-pub const B: u8 = 200u8 + 200u8; //~ ERROR attempted to add with overflow
-pub const C: u8 = 200u8 * 4; //~ ERROR attempted to multiply with overflow
-pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR attempted to subtract with overflow
+pub const A: i8 = -std::i8::MIN; //~ ERROR attempt to negate with overflow
+pub const B: u8 = 200u8 + 200u8; //~ ERROR attempt to add with overflow
+pub const C: u8 = 200u8 * 4; //~ ERROR attempt to multiply with overflow
+pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR attempt to subtract with overflow
 pub const E: u8 = [5u8][1];
 //~^ ERROR index out of bounds: the len is 1 but the index is 1
 
index 7de93a213b02212485784db0b469203180e7bef1..d4f9c0fe56dae4645af8f37e178cfad831ca2a87 100644 (file)
@@ -10,7 +10,7 @@
 
 #![deny(const_err)]
 
-pub const A: i8 = -std::i8::MIN; //~ ERROR attempted to negate with overflow
+pub const A: i8 = -std::i8::MIN; //~ ERROR attempt to negate with overflow
 pub const B: i8 = A;
 pub const C: u8 = A as u8;
 pub const D: i8 = 50 - A;
index f2079800cad311e624ee9ca644603877889353d1..944e458c4c0f03db09a25a11c2e5e3565e45b398 100644 (file)
@@ -30,18 +30,18 @@ fn black_box<T>(_: T) {
 fn main() {
     let a = -std::i8::MIN;
     //~^ WARN this expression will panic at run-time
-    //~| attempted to negate with overflow
+    //~| attempt to negate with overflow
     let b = 200u8 + 200u8 + 200u8;
     //~^ WARN this expression will panic at run-time
-    //~| attempted to add with overflow
+    //~| attempt to add with overflow
     //~^^^ WARN this expression will panic at run-time
-    //~| attempted to add with overflow
+    //~| attempt to add with overflow
     let c = 200u8 * 4;
     //~^ WARN this expression will panic at run-time
-    //~| attempted to multiply with overflow
+    //~| attempt to multiply with overflow
     let d = 42u8 - (42u8 + 1);
     //~^ WARN this expression will panic at run-time
-    //~| attempted to subtract with overflow
+    //~| attempt to subtract with overflow
     let _e = [5u8][1];
     //~^ WARN this expression will panic at run-time
     //~| index out of bounds: the len is 1 but the index is 1
index f0d65f1424c464bed7b4bc06b3bedb511fd66cfd..7c1fb2ccd47297594b53f62bb6a6e3c270067d00 100644 (file)
@@ -18,14 +18,14 @@ fn black_box<T>(_: T) {
 
 fn main() {
     let a = -std::i8::MIN;
-    //~^ ERROR attempted to negate with overflow
+    //~^ ERROR attempt to negate with overflow
     let b = 200u8 + 200u8 + 200u8;
-    //~^ ERROR attempted to add with overflow
-    //~| ERROR attempted to add with overflow
+    //~^ ERROR attempt to add with overflow
+    //~| ERROR attempt to add with overflow
     let c = 200u8 * 4;
-    //~^ ERROR attempted to multiply with overflow
+    //~^ ERROR attempt to multiply with overflow
     let d = 42u8 - (42u8 + 1);
-    //~^ ERROR attempted to subtract with overflow
+    //~^ ERROR attempt to subtract with overflow
     let _e = [5u8][1];
     black_box(a);
     black_box(b);
index 4749457da8814ba89b294c624f1397770bb495ae..264f02588ae5dbca1636c2d27a8ab91ddfa1df51 100644 (file)
 const NEG_128: i8 = -128;
 const NEG_NEG_128: i8 = -NEG_128;
 //~^ ERROR constant evaluation error
-//~| attempted to negate with overflow
+//~| attempt to negate with overflow
 //~| ERROR constant evaluation error
-//~| attempted to negate with overflow
+//~| attempt to negate with overflow
 //~| ERROR constant evaluation error
-//~| attempted to negate with overflow
+//~| attempt to negate with overflow
 
 fn main() {
     match -128i8 {
index c78c74e9e231b5d8ccfdfbf1b2b250c6e1e4afba..d930cb770472ffc64c9b1ead3459effc3a2732d3 100644 (file)
@@ -17,7 +17,7 @@
 // self-hosted and a cross-compiled setup; therefore resorting to
 // error-pattern for now.
 
-// error-pattern: attempted to add with overflow
+// error-pattern: attempt to add with overflow
 
 #![allow(unused_imports)]
 
index f1f125adaa7e330a73db146083c15493a53ab1bf..67525fc16261b252f7aa679ba3c1f2ce76f06221 100644 (file)
@@ -23,7 +23,7 @@
 
 const A_I8_T
     : [u32; (i8::MAX as i8 + 1i8) as usize]
-    //~^ ERROR error evaluating count: attempted to add with overflow
+    //~^ ERROR error evaluating count: attempt to add with overflow
     = [0; (i8::MAX as usize) + 1];
 
 fn main() {
index c1c693544fa96e7fd224ebdeceb01341a3894d2e..b8f3f714a84ec89811235ddbcfaee993cb608f26 100644 (file)
 const VALS_I8: (i8, i8, i8, i8) =
     (-i8::MIN,
      //~^ ERROR constant evaluation error
-     //~| attempted to negate with overflow
+     //~| attempt to negate with overflow
      i8::MIN - 1,
      //~^ ERROR constant evaluation error
-     //~| attempted to subtract with overflow
+     //~| attempt to subtract with overflow
      i8::MAX + 1,
      //~^ ERROR constant evaluation error
-     //~| attempted to add with overflow
+     //~| attempt to add with overflow
      i8::MIN * 2,
      //~^ ERROR constant evaluation error
-     //~| attempted to multiply with overflow
+     //~| attempt to multiply with overflow
      );
 
 const VALS_I16: (i16, i16, i16, i16) =
     (-i16::MIN,
      //~^ ERROR constant evaluation error
-     //~| attempted to negate with overflow
+     //~| attempt to negate with overflow
      i16::MIN - 1,
      //~^ ERROR constant evaluation error
-     //~| attempted to subtract with overflow
+     //~| attempt to subtract with overflow
      i16::MAX + 1,
      //~^ ERROR constant evaluation error
-     //~| attempted to add with overflow
+     //~| attempt to add with overflow
      i16::MIN * 2,
      //~^ ERROR constant evaluation error
-     //~| attempted to multiply with overflow
+     //~| attempt to multiply with overflow
      );
 
 const VALS_I32: (i32, i32, i32, i32) =
     (-i32::MIN,
      //~^ ERROR constant evaluation error
-     //~| attempted to negate with overflow
+     //~| attempt to negate with overflow
      i32::MIN - 1,
      //~^ ERROR constant evaluation error
-     //~| attempted to subtract with overflow
+     //~| attempt to subtract with overflow
      i32::MAX + 1,
      //~^ ERROR constant evaluation error
-     //~| attempted to add with overflow
+     //~| attempt to add with overflow
      i32::MIN * 2,
      //~^ ERROR constant evaluation error
-     //~| attempted to multiply with overflow
+     //~| attempt to multiply with overflow
      );
 
 const VALS_I64: (i64, i64, i64, i64) =
     (-i64::MIN,
      //~^ ERROR constant evaluation error
-     //~| attempted to negate with overflow
+     //~| attempt to negate with overflow
      i64::MIN - 1,
      //~^ ERROR constant evaluation error
-     //~| attempted to subtract with overflow
+     //~| attempt to subtract with overflow
      i64::MAX + 1,
      //~^ ERROR constant evaluation error
-     //~| attempted to add with overflow
+     //~| attempt to add with overflow
      i64::MAX * 2,
      //~^ ERROR constant evaluation error
-     //~| attempted to multiply with overflow
+     //~| attempt to multiply with overflow
      );
 
 const VALS_U8: (u8, u8, u8, u8) =
     (-(u8::MIN as i8) as u8,
      u8::MIN - 1,
      //~^ ERROR constant evaluation error
-     //~| attempted to subtract with overflow
+     //~| attempt to subtract with overflow
      u8::MAX + 1,
      //~^ ERROR constant evaluation error
-     //~| attempted to add with overflow
+     //~| attempt to add with overflow
      u8::MAX * 2,
      //~^ ERROR constant evaluation error
-     //~| attempted to multiply with overflow
+     //~| attempt to multiply with overflow
      );
 
 const VALS_U16: (u16, u16, u16, u16) =
     (-(u16::MIN as i16) as u16,
      u16::MIN - 1,
      //~^ ERROR constant evaluation error
-     //~| attempted to subtract with overflow
+     //~| attempt to subtract with overflow
      u16::MAX + 1,
      //~^ ERROR constant evaluation error
-     //~| attempted to add with overflow
+     //~| attempt to add with overflow
      u16::MAX * 2,
      //~^ ERROR constant evaluation error
-     //~| attempted to multiply with overflow
+     //~| attempt to multiply with overflow
      );
 
 const VALS_U32: (u32, u32, u32, u32) =
     (-(u32::MIN as i32) as u32,
      u32::MIN - 1,
      //~^ ERROR constant evaluation error
-     //~| attempted to subtract with overflow
+     //~| attempt to subtract with overflow
      u32::MAX + 1,
      //~^ ERROR constant evaluation error
-     //~| attempted to add with overflow
+     //~| attempt to add with overflow
      u32::MAX * 2,
      //~^ ERROR constant evaluation error
-     //~| attempted to multiply with overflow
+     //~| attempt to multiply with overflow
      );
 
 const VALS_U64: (u64, u64, u64, u64) =
     (-(u64::MIN as i64) as u64,
      u64::MIN - 1,
      //~^ ERROR constant evaluation error
-     //~| attempted to subtract with overflow
+     //~| attempt to subtract with overflow
      u64::MAX + 1,
      //~^ ERROR constant evaluation error
-     //~| attempted to add with overflow
+     //~| attempt to add with overflow
      u64::MAX * 2,
      //~^ ERROR constant evaluation error
-     //~| attempted to multiply with overflow
+     //~| attempt to multiply with overflow
      );
 
 fn main() {
index d813cf32954e3349edcbfe5c1e21a7d3bb6af584..92568b27f7c1da143e24a4fd2a982f3df13026d7 100644 (file)
@@ -20,7 +20,9 @@ trait Foo {
 }
 
 impl Foo for u32 {
-    const fn f() -> u32 { 22 } //~ ERROR E0379
+    const fn f() -> u32 { 22 }
+    //~^ ERROR E0379
+    //~| NOTE trait fns cannot be const
 }
 
 fn main() { }
index 5dadd892f83520cca532436ce88986e7b4649476..398dc2f22150cc8c90fc1daf0ee9030990b00c86 100644 (file)
 const ARR3: [i32; X3] = [99; 6]; //~ NOTE: for array length here
 
 const Y: usize = 42.0 == 42.0;
-const ARRR: [i32; Y] = [99; 1]; //~ ERROR: expected usize for array length
+const ARRR: [i32; Y] = [99; 1];
+//~^ ERROR: expected `usize` for array length, found boolean [E0306]
+//~| NOTE expected `usize`
+
 const Y1: usize = 42.0 >= 42.0;
-const ARRR1: [i32; Y] = [99; 1]; //~ ERROR: expected usize for array length
+const ARRR1: [i32; Y] = [99; 1];
+//~^ ERROR: expected `usize` for array length, found boolean [E0306]
+//~| NOTE expected `usize`
+
 const Y2: usize = 42.0 <= 42.0;
-const ARRR2: [i32; Y] = [99; 1]; //~ ERROR: expected usize for array length
+const ARRR2: [i32; Y] = [99; 1];
+//~^ ERROR: expected `usize` for array length, found boolean [E0306]
+//~| NOTE expected `usize`
+
 const Y3: usize = 42.0 > 42.0;
-const ARRR3: [i32; Y] = [99; 0]; //~ ERROR: expected usize for array length
+const ARRR3: [i32; Y] = [99; 0];
+//~^ ERROR: expected `usize` for array length, found boolean [E0306]
+//~| NOTE expected `usize`
+
 const Y4: usize = 42.0 < 42.0;
-const ARRR4: [i32; Y] = [99; 0]; //~ ERROR: expected usize for array length
+const ARRR4: [i32; Y] = [99; 0];
+//~^ ERROR: expected `usize` for array length, found boolean [E0306]
+//~| NOTE expected `usize`
+
 const Y5: usize = 42.0 != 42.0;
-const ARRR5: [i32; Y] = [99; 0]; //~ ERROR: expected usize for array length
+const ARRR5: [i32; Y] = [99; 0];
+//~^ ERROR: expected `usize` for array length, found boolean [E0306]
+//~| NOTE expected `usize`
+
 
 fn main() {
     let _ = ARR;
index 43375ee3d18968e83645b150088189cdfef4a9ea..c01bb82676304f1581af586d85520b13a977861c 100644 (file)
@@ -16,7 +16,7 @@
 const TWO: usize = 2;
 const LEN: usize = ONE - TWO;
 //~^ ERROR E0080
-//~| attempted to subtract with overflow
+//~| attempt to subtract with overflow
 
 fn main() {
     let a: [i8; LEN] = unimplemented!();
index e338f206553b422110dc9086c5190878b02f91c5..7f2229b5a6534c868910d7c42e834bd6f16337de 100644 (file)
@@ -17,5 +17,5 @@
 fn main() {
     let a: [i8; ONE - TWO] = unimplemented!();
     //~^ ERROR constant evaluation error [E0080]
-    //~| attempted to subtract with overflow
+    //~| attempt to subtract with overflow
 }
index 75b6397f4ebd71ac5c7260acb3c93b57179aa481..11003067070f4e99b01f9cdfd1a55cd4253b4c75 100644 (file)
@@ -25,4 +25,5 @@ fn main() {
                //~^ NOTE cannot be named the same as a constant
     let d = 4; //~ ERROR let bindings cannot shadow constants
                //~^ NOTE cannot be named the same as a constant
+    fn f() {} // Check that the `NOTE`s still work with an item here (c.f. issue #35115).
 }
index 6f095b3041ffedc833eef1b3ecc985f809ca60d9..8f7ec9de58af2bda03ee30398d18c8893cbfc6b5 100644 (file)
@@ -12,7 +12,7 @@
 
 const TUP: (usize,) = 5 << 64;
 //~^ ERROR E0080
-//~| attempted to shift left with overflow
+//~| attempt to shift left with overflow
 const ARR: [i32; TUP.0] = [];
 
 fn main() {
diff --git a/src/test/compile-fail/deprecation-lint-nested.rs b/src/test/compile-fail/deprecation-lint-nested.rs
new file mode 100644 (file)
index 0000000..eedbba5
--- /dev/null
@@ -0,0 +1,81 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![deny(deprecated)]
+#![allow(warnings)]
+
+#[deprecated]
+fn issue_35128() {
+    format_args!("foo");
+}
+
+#[deprecated]
+fn issue_35128_minimal() {
+    static FOO: &'static str = "foo";
+    let _ = FOO;
+}
+
+#[deprecated]
+mod silent {
+    type DeprecatedType = u8;
+    struct DeprecatedStruct;
+    fn deprecated_fn() {}
+    trait DeprecatedTrait {}
+    static DEPRECATED_STATIC: u8 = 0;
+    const DEPRECATED_CONST: u8 = 1;
+
+    struct Foo(DeprecatedType);
+
+    impl DeprecatedTrait for Foo {}
+
+    impl Foo {
+        fn bar<T: DeprecatedTrait>() {
+            deprecated_fn();
+        }
+    }
+
+    fn foo() -> u8 {
+        DEPRECATED_STATIC +
+        DEPRECATED_CONST
+    }
+}
+
+#[deprecated]
+mod loud {
+    #[deprecated]
+    type DeprecatedType = u8;
+    #[deprecated]
+    struct DeprecatedStruct;
+    #[deprecated]
+    fn deprecated_fn() {}
+    #[deprecated]
+    trait DeprecatedTrait {}
+    #[deprecated]
+    static DEPRECATED_STATIC: u8 = 0;
+    #[deprecated]
+    const DEPRECATED_CONST: u8 = 1;
+
+    struct Foo(DeprecatedType); //~ ERROR use of deprecated item
+
+    impl DeprecatedTrait for Foo {} //~ ERROR use of deprecated item
+
+    impl Foo {
+        fn bar<T: DeprecatedTrait>() { //~ ERROR use of deprecated item
+            deprecated_fn(); //~ ERROR use of deprecated item
+        }
+    }
+
+    fn foo() -> u8 {
+        DEPRECATED_STATIC + //~ ERROR use of deprecated item
+        DEPRECATED_CONST //~ ERROR use of deprecated item
+    }
+}
+
+fn main() {}
index 5fc8f684a66fe01f678fdc4cb3bde67a7f15a6f3..edee24206cd33b43224ea900488cc962929912d8 100644 (file)
@@ -266,14 +266,14 @@ fn test_method_object(foo: &Trait) {
     #[deprecated(since = "1.0.0", note = "text")]
     fn test_fn_body() {
         fn fn_in_body() {}
-        fn_in_body(); //~ ERROR use of deprecated item: text
+        fn_in_body();
     }
 
     impl MethodTester {
         #[deprecated(since = "1.0.0", note = "text")]
         fn test_method_body(&self) {
             fn fn_in_body() {}
-            fn_in_body(); //~ ERROR use of deprecated item: text
+            fn_in_body();
         }
     }
 
index 7b915647884f2ac169a6e45f43b1b1f0083c8c2d..bd190a6df8e39f97153e0b76862e97f42ef3e452 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-#![feature(no_core)]
-#![no_core]
 
 // This tests that conflicting imports shows both `use` lines
 // when reporting the error.
@@ -23,5 +21,6 @@ pub fn foo() {} // implementation 2
 
 use sub1::foo; //~ NOTE previous import of `foo` here
 use sub2::foo; //~ ERROR a value named `foo` has already been imported in this module [E0252]
+               //~| NOTE already imported
 
 fn main() {}
diff --git a/src/test/compile-fail/enable-orbit-for-incr-comp.rs b/src/test/compile-fail/enable-orbit-for-incr-comp.rs
new file mode 100644 (file)
index 0000000..eec6bad
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-pretty
+// compile-flags:-Zincremental=tmp/cfail-tests/enable-orbit-for-incr-comp -Zorbit=off
+// error-pattern:Automatically enabling `-Z orbit` because `-Z incremental` was specified
+
+#![deny(warnings)]
+
+fn main() {
+    FAIL! // We just need some compilation error. What we really care about is
+          // that the error pattern above is checked.
+}
index 57db583aefe2355cb46bde8df1027c98637b18e7..86cc2c144ac07dd2a0169d5abdd69f0a742b336e 100644 (file)
 
 enum test {
     div_zero = 1/0, //~ ERROR E0080
-                    //~| attempted to divide by zero
+                    //~| attempt to divide by zero
     rem_zero = 1%0,
     //~^ ERROR E0080
-    //~| attempted to calculate the remainder with a divisor of zero
+    //~| attempt to calculate the remainder with a divisor of zero
 }
 
 fn main() {}
index 37737fda4749e5004ce1e666560e0da343143158..d9ac715fa9548447340e9f33633299676fb352ae 100644 (file)
@@ -16,5 +16,7 @@ struct Vec<T, A = Heap>(
     marker::PhantomData<(T,A)>);
 
 fn main() {
-    let _: Vec; //~ ERROR wrong number of type arguments: expected at least 1, found 0
+    let _: Vec;
+    //~^ ERROR E0243
+    //~| NOTE expected at least 1 type arguments, found 0
 }
index ad7e4f190c5b9df7fe358c88f9b51461e8024479..8f733ddfce187f7c73b58d82e652be928597b0be 100644 (file)
@@ -17,5 +17,6 @@ struct Vec<T, A = Heap>(
 
 fn main() {
     let _: Vec<isize, Heap, bool>;
-    //~^ ERROR wrong number of type arguments: expected at most 2, found 3
+    //~^ ERROR E0244
+    //~| NOTE expected at most 2 type arguments, found 3
 }
index 981eddc9dd96b20d502cf8523615be8bf7e3233f..f6e9ab2d614bce630b7f8dae5a1d8f56e2f8576e 100644 (file)
@@ -12,7 +12,9 @@
 
 impl Foo {
     fn orange(&self) {} //~ NOTE previous definition of `orange` here
-    fn orange(&self) {} //~ ERROR duplicate definitions with name `orange`
+    fn orange(&self) {}
+    //~^ ERROR duplicate definition
+    //~| NOTE duplicate definition
 }
 
 fn main() {}
index 23401db21d89063643045ccf10d4fcac92783807..d48433ee928f1eb2b7c84d6133045766b3e14f3e 100644 (file)
@@ -19,6 +19,7 @@ trait Fun {
 struct Holder { x: String }
 
 impl<'a> Fun for Holder { //~ ERROR E0207
+                          //~| NOTE unconstrained lifetime parameter
     type Output = &'a str;
     fn call<'b>(&'b self) -> &'b str {
         &self.x[..]
index 9b3e28cbc01ee4eaa4cf98d746a6a9731c914a3c..e0ea1a4cac58bb83102cacf447fb478961897928 100644 (file)
 
 trait Foo {
     fn bar(&self);
-    const MY_CONST: u32;
+    //~^ NOTE original trait requirement
+    //~| NOTE original trait requirement
+    const MY_CONST: u32; //~ NOTE original trait requirement
 }
 
 pub struct FooConstForMethod;
 
 impl Foo for FooConstForMethod {
     //~^ ERROR E0046
+    //~| NOTE missing `bar` in implementation
     const bar: u64 = 1;
     //~^ ERROR E0323
+    //~| NOTE does not match trait
     const MY_CONST: u32 = 1;
 }
 
@@ -28,17 +32,21 @@ impl Foo for FooConstForMethod {
 
 impl Foo for FooMethodForConst {
     //~^ ERROR E0046
+    //~| NOTE missing `MY_CONST` in implementation
     fn bar(&self) {}
     fn MY_CONST() {}
     //~^ ERROR E0324
+    //~| NOTE does not match trait
 }
 
 pub struct FooTypeForMethod;
 
 impl Foo for FooTypeForMethod {
     //~^ ERROR E0046
+    //~| NOTE missing `bar` in implementation
     type bar = u64;
     //~^ ERROR E0325
+    //~| NOTE does not match trait
     const MY_CONST: u32 = 1;
 }
 
index 5322966ae2ea0544a78d19a242c8d592a74187d2..001e4b51bebc4f619beaa84665fb38a7d6ecf525 100644 (file)
@@ -14,5 +14,7 @@ fn new<T>() -> &'static T {
 
 fn main() {
     let &v = new();
-    //~^ ERROR type annotations or generic parameter binding required
+    //~^ ERROR unable to infer enough type information about `_` [E0282]
+    //~| NOTE cannot infer type for `_`
+    //~| NOTE type annotations or generic parameter binding
 }
index dabc0acba370e07a4344f577306d9752f6fcbf22..7cbee402b368253cb59845e912ed357307f77f33 100644 (file)
@@ -14,5 +14,7 @@ fn new<'r, T>() -> &'r T {
 
 fn main() {
     let &v = new();
-    //~^ ERROR type annotations or generic parameter binding required
+    //~^ ERROR unable to infer enough type information about `_` [E0282]
+    //~| NOTE cannot infer type for `_`
+    //~| NOTE type annotations or generic parameter binding
 }
index c87dcb8ae79b21119b3b01b4ccd13b1afa1d4949..dd02fa7ac151c10186bd633726d7dc2567896f8f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn fn1(0: Box) {} //~ ERROR: wrong number of type arguments: expected 1, found 0
+fn fn1(0: Box) {}
+        //~^ ERROR E0243
+        //~| NOTE expected 1 type arguments, found 0
 
 fn main() {}
index bdf344dcdfe8da8377ba866e99756a1fb1ad3b39..3d6f224c249040a1c1d168d0b5357ba9af7c06de 100644 (file)
 
 enum Foo {
     A = 1,
-    B = 1, //~ ERROR discriminant value `1isize` already exists
-    //~^^ NOTE conflicting
+    //~^ NOTE first use
+    //~| NOTE first use
+    //~| NOTE first use
+    B = 1, //~ ERROR discriminant value
+    //~^ NOTE enum already
     C = 0,
-    D, //~ ERROR discriminant value `1isize` already exists
-    //~^^^^^ NOTE conflicting
-    E = N, //~ ERROR discriminant value `1isize` already exists
-    //~^^^^^^^ NOTE conflicting
+    D, //~ ERROR discriminant value
+    //~^ NOTE enum already
+
+    E = N, //~ ERROR discriminant value
+    //~^ NOTE enum already
+
 }
 
 fn main() {}
index 3591b9824145bbdd2d114d457727baf2e6143425..cf650460c3de11408e6acc898303b5964f2e18de 100644 (file)
@@ -23,6 +23,8 @@ fn print_x(_: &Foo<Item=bool>, extra: &str) {
 }
 
 fn main() {
-    print_x(X);  //~error this function takes 2 parameters but 1 parameter was supplied
-    //~^ NOTE the following parameter types were expected: &Foo<Item=bool>, &str
+    print_x(X);
+    //~^ ERROR this function takes 2 parameters but 1 parameter was supplied
+    //~| NOTE the following parameter types were expected: &Foo<Item=bool>, &str
+    //~| NOTE expected 2 parameters
 }
index 4aa2571cad0cc9418709407687ff5ba9ac19056d..d258a4a8b3325b18149d8dd641a3c6d49534a46b 100644 (file)
@@ -21,6 +21,7 @@ fn crash_please() {
 struct Newtype(Option<Box<usize>>);
 
 impl<'a> Iterator for Newtype { //~ ERROR E0207
+                                //~| NOTE unconstrained lifetime parameter
     type Item = &'a Box<usize>;
 
     fn next(&mut self) -> Option<&Box<usize>> {
index df2a70160f866e58bafe4a9c4b06518e7493f747..e266f004317e7f46d1adb52b8bb96498bc56acad 100644 (file)
@@ -18,6 +18,6 @@ fn h(x:i32) -> i32 {3*x}
     vfnfer.push(box h);
     println!("{:?}",(vfnfer[0] as Fn)(3));
     //~^ ERROR the precise format of `Fn`-family traits'
-    //~| ERROR wrong number of type arguments: expected 1, found 0
+    //~| ERROR E0243
     //~| ERROR the value of the associated type `Output` (from the trait `std::ops::FnOnce`)
 }
index 1a9bb4c29f3e0183ad2f0a6a0cf45e5dd44f0214..1be082ba9bbbad454982a42a82d8ce3e7c4b6361 100644 (file)
@@ -14,4 +14,6 @@ fn main()
     fn bar(x:i32) ->i32 { 3*x };
     let b:Box<Any> = Box::new(bar as fn(_)->_);
     b.downcast_ref::<fn(_)->_>(); //~ ERROR E0282
+                                  //~| NOTE cannot infer type for `_`
+                                  //~| NOTE type annotations or generic parameter binding required
 }
index 4ed44154c4748ce51514dc0201904507127a0a2d..f1c559b6b889f207cdc7e4542cd60de3895775a3 100644 (file)
@@ -16,6 +16,7 @@ pub trait D {
     fn f<T>(self)
         where T<Bogus = Foo>: A;
         //~^ ERROR associated type bindings are not allowed here [E0229]
+        //~| NOTE associate type not allowed here
 }
 
 fn main() {}
index 1d7c2187045ea28efdfe5925b5214437cc863a55..3959c22d1d489384a9baccac9b838ad467fcd2af 100644 (file)
@@ -14,6 +14,7 @@ pub trait D {
     fn f<T>(self)
         where T<Bogus = Self::AlsoBogus>: A;
         //~^ ERROR associated type bindings are not allowed here [E0229]
+        //~| NOTE associate type not allowed here
 }
 
 fn main() {}
index f98cf6575d6ec5b2340b65bd2b8cd27462762b81..b1047ce18cccdf552ce6bd2ceee305fe78fe5a81 100644 (file)
@@ -18,7 +18,8 @@ struct Recurrence {
         }
 
         impl Iterator for Recurrence {
-            //~^ ERROR not all trait items implemented, missing: `Item` [E0046]
+            //~^ ERROR E0046
+            //~| NOTE missing `Item` in implementation
             #[inline]
             fn next(&mut self) -> Option<u64> {
                 if self.pos < 2 {
index 6c42c88bee6d09ee72a5e3870dd28faa54f3882a..2062e2373129bd77d698d0aa555743dd85d0494d 100644 (file)
@@ -34,7 +34,8 @@ extern "rust-call" fn call_mut(&mut self, (comp,): (C,)) -> Prototype {
 }
 
 impl<C: Component> FnOnce<(C,)> for Prototype {
-    //~^ ERROR not all trait items implemented, missing: `Output` [E0046]
+    //~^ ERROR E0046
+    //~| NOTE missing `Output` in implementation
     extern "rust-call" fn call_once(self, (comp,): (C,)) -> Prototype {
         Fn::call(&self, (comp,))
     }
index ede81bea32ae3bfaea3db5168a4ea23f2ed19a1d..d39fd539dcebc301350cc85ba5e606408c774f20 100644 (file)
@@ -28,7 +28,8 @@ fn deref(&self) -> &i8 { &self.0 }
 
         // Causes ICE
         impl Deref for Thing {
-            //~^ ERROR not all trait items implemented, missing: `Target` [E0046]
+            //~^ ERROR E0046
+            //~| NOTE missing `Target` in implementation
             fn deref(&self) -> i8 { self.0 }
         }
 
index c849716f21a378d20c55d75d46520a1faa195a3f..46e82363c8bd832597d76b525427754b9c0a0a51 100644 (file)
@@ -11,7 +11,9 @@
 use std::sync::{self, Arc}; //~ NOTE previous import
                             //~^ NOTE previous import
 use std::sync::Arc; //~ ERROR a type named
+                    //~| NOTE already imported
 use std::sync; //~ ERROR a module named
+               //~| NOTE already imported
 
 fn main() {
 }
index ee6ec52761266607887eef14302a41e2102c6278..e89bff025e006bf6fed83b4939302027ecadf66f 100644 (file)
@@ -16,5 +16,6 @@ fn main() {
     //~| expected type `usize`
     //~| found type `S`
     //~| expected usize, found struct `S`
-    //~| ERROR expected usize for repeat count, found struct
+    //~| ERROR expected `usize` for repeat count, found struct [E0306]
+    //~| expected `usize`
 }
index 6a97ae82ddf317685d0f72e11c6cf2938693d29a..ce3fa487d4e02fa0b892acf8d676340b50a18a22 100644 (file)
@@ -10,7 +10,7 @@
 
 struct Foo;
 #[derive(Copy, Clone)]
-//~^ ERROR the trait `Copy` may not be implemented for this type; field `0` does not implement
+//~^ ERROR the trait `Copy` may not be implemented for this type
 struct Bar(Foo);
 
 fn main() {}
index 7c051784f61a7dbbf253550c40cb03dffad0dcee..f03daafc63754b533828feddb9f3d8641c0d0c3b 100644 (file)
 struct MyStruct;
 
 impl Drop for MyStruct {
-//~^ NOTE conflicting implementation is here
+//~^ NOTE first implementation here
     fn drop(&mut self) { }
 }
 
 impl Drop for MyStruct {
 //~^ ERROR conflicting implementations of trait
+//~| NOTE conflicting implementation for `MyStruct`
     fn drop(&mut self) { }
 }
 
index 68046056fb3156eebb5691b80a0f82c6e06eabd7..d19e3b2c7b0a8c40d8193ac10b497e8151d353ad 100644 (file)
@@ -14,7 +14,7 @@ fn main() {
     needlesArr.iter().fold(|x, y| {
     });
     //~^^ ERROR this function takes 2 parameters but 1 parameter was supplied
-    //~^^^ NOTE the following parameter types were expected
-    //
+    //~| NOTE the following parameter types were expected
+    //~| NOTE expected 2 parameters
     // the first error is, um, non-ideal.
 }
index 2b3df9ad1d83b7fe8dc02bb3fff1c65fec2bdfbd..4997a6fee195b4c736816bd9c6d3bc150ac8c425 100644 (file)
@@ -22,6 +22,7 @@ fn main() {
         //~^ NOTE this pattern matches any value
         Var2 => (),
         //~^ ERROR unreachable pattern
+        //~^^ NOTE this is an unreachable pattern
     };
     match &s {
         &Var1 => (),
@@ -29,6 +30,7 @@ fn main() {
         //~^ NOTE this pattern matches any value
         &Var2 => (),
         //~^ ERROR unreachable pattern
+        //~^^ NOTE this is an unreachable pattern
     };
     let t = (Var1, Var1);
     match t {
@@ -37,6 +39,7 @@ fn main() {
         //~^ NOTE this pattern matches any value
         anything => ()
         //~^ ERROR unreachable pattern
+        //~^^ NOTE this is an unreachable pattern
     };
     // `_` need not emit a note, it is pretty obvious already.
     let t = (Var1, Var1);
@@ -45,5 +48,6 @@ fn main() {
         _ => (),
         anything => ()
         //~^ ERROR unreachable pattern
+        //~^^ NOTE this is an unreachable pattern
     };
 }
diff --git a/src/test/compile-fail/issue-33784.rs b/src/test/compile-fail/issue-33784.rs
new file mode 100644 (file)
index 0000000..4229be2
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::ops::Deref;
+
+struct Obj<F> where F: FnMut() -> u32 {
+    fn_ptr: fn() -> (),
+    closure: F,
+}
+
+struct C {
+    c_fn_ptr: fn() -> (),
+}
+
+struct D(C);
+
+impl Deref for D {
+    type Target = C;
+    fn deref(&self) -> &C {
+        &self.0
+    }
+}
+
+
+fn empty() {}
+
+fn main() {
+    let o = Obj { fn_ptr: empty, closure: || 42 };
+    let p = &o;
+    p.closure(); //~ ERROR no method named `closure` found
+    //~^ NOTE use `(p.closure)(...)` if you meant to call the function stored in the `closure` field
+    let q = &p;
+    q.fn_ptr(); //~ ERROR no method named `fn_ptr` found
+    //~^ NOTE use `(q.fn_ptr)(...)` if you meant to call the function stored in the `fn_ptr` field
+    let r = D(C { c_fn_ptr: empty });
+    let s = &r;
+    s.c_fn_ptr(); //~ ERROR no method named `c_fn_ptr` found
+    //~^ NOTE use `(s.c_fn_ptr)(...)` if you meant to call the function stored in the `c_fn_ptr`
+}
index 6fae18dec10a67e602338a3f15de815a623b1589..5e3b777cc0b62cd845cb9af92176b3c64a590d8c 100644 (file)
@@ -15,7 +15,9 @@ enum S {
 fn bug(l: S) {
     match l {
         S::B{ } => { },
-        //~^ ERROR ambiguous associated type; specify the type using the syntax `<S as Trait>::B`
+        //~^ ERROR ambiguous associated type
+        //~| NOTE ambiguous associated type
+        //~| NOTE specify the type using the syntax `<S as Trait>::B`
     }
 }
 
index 67f0e7aaf9717ee68161684dccc9d3ee6caf026c..5c4f161a5004ed9c20c190da2fe38468d8a98eac 100644 (file)
@@ -17,6 +17,7 @@ pub trait MethodType {
 pub struct MTFn;
 
 impl<'a> MethodType for MTFn { //~ ERROR E0207
+                               //~| NOTE unconstrained lifetime parameter
     type GetProp = fmt::Debug + 'a;
 }
 
index c99ff1813e0d12b78cbefabba88b74551a4494b0..93556577ad345c66381d3452cb146cf4ea17e577 100644 (file)
 // aux-build:issue_3907.rs
 extern crate issue_3907;
 
-type Foo = issue_3907::Foo; //~ NOTE: type aliases cannot be used for traits
+type Foo = issue_3907::Foo;
 
 struct S {
     name: isize
 }
 
 impl Foo for S { //~ ERROR: `Foo` is not a trait
-    //~| `Foo` is not a trait
+                 //~| NOTE: not a trait
+                 //~| NOTE: type aliases cannot be used for traits
     fn bar() { }
 }
 
index 9a1b5d9b83d2c27a910164b0d687567dca23b43f..09371fbafcb560f98e91acab4a483709a4745a6b 100644 (file)
@@ -14,7 +14,10 @@ fn f<'r, T>(v: &'r T) -> Box<FnMut() -> T + 'r> {
     // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
     id(Box::new(|| *v))
         //~^ ERROR E0373
-        //~| ERROR cannot move out of borrowed content
+        //~| NOTE `v` is borrowed here
+        //~| NOTE may outlive borrowed value `v`
+        //~| ERROR E0507
+        //~| NOTE cannot move out of borrowed content
 }
 
 fn main() {
index 438d238b6fe6288c8c7202c6208dd42b2114ae30..58a84f3490b3c47f3b2f74a4da21fcb7900c00b6 100644 (file)
@@ -11,5 +11,7 @@
 // Regression test for issue #4935
 
 fn foo(a: usize) {}
-fn main() { foo(5, 6) } //~ ERROR this function takes 1 parameter but 2 parameters were supplied
-//~^ NOTE the following parameter type was expected
+fn main() { foo(5, 6) }
+//~^ ERROR this function takes 1 parameter but 2 parameters were supplied
+//~| NOTE the following parameter type was expected
+//~| NOTE expected 1 parameter
index a186a399a112c1f614ac16616b5c9d0a04e8ecf7..c2154e8a6c0b605ce78e135875aa19a2e414ecf9 100644 (file)
 
 trait I {}
 type K = I;
-//~^ NOTE: aliases cannot be used for traits
 impl K for isize {} //~ ERROR: `K` is not a trait
-//~| is not a trait
+                    //~| NOTE: not a trait
+                    //~| NOTE: aliases cannot be used for traits
+
+use ImportError; //~ ERROR unresolved
+impl ImportError for () {} // check that this is not an additional error (c.f. #35142)
+
 fn main() {}
index 392d38a6144f19d5364d12ec0363d41881d8d44e..f5aa4fadbed88605886670d9165c9e4ce41fd759 100644 (file)
@@ -9,4 +9,4 @@
 // except according to those terms.
 
 fn main() { format!("{:?}", None); }
-    //~^ ERROR type annotations or generic parameter binding required
+    //~^ ERROR unable to infer enough type information about `_` [E0282]
index 1ebef06008ffa4f3c6b345dee1cd6110d7d62132..06e3c9a207b78c8d11007a54700ea75314457cd1 100644 (file)
@@ -13,4 +13,5 @@
 fn main() {
     let x = |ref x: isize| -> isize { x += 1; };
     //~^ ERROR E0368
+    //~| NOTE cannot use `+=` on type `&isize`
 }
index acf1d766b6a11a65107d768ba7ee1e094b32e1e7..71f28054579157b40e159f1d924e72b8b4913bcc 100644 (file)
@@ -11,5 +11,5 @@
 fn main() {
     // Unconstrained type:
     format!("{:?}", None);
-    //~^ ERROR type annotations or generic parameter binding required
+    //~^ ERROR unable to infer enough type information about `_` [E0282]
 }
index 3f81e51efe2ef40badd39877f31a4780da6a7b9a..e397805565bbdcd95c036d8f1ce6ff45dbe560be 100644 (file)
@@ -12,5 +12,7 @@
 
 fn main() {
     mem::transmute(0);
-    //~^ ERROR type annotations or generic parameter binding required
+    //~^ ERROR unable to infer enough type information about `_` [E0282]
+    //~| NOTE cannot infer type for `_`
+    //~| NOTE type annotations or generic parameter binding
 }
index 7f408be9c02d4c77dc3c9da9b97371b254748c1a..c3f3a718ad0e21cf5c6a91ec11b62fe5031d442f 100644 (file)
@@ -10,7 +10,9 @@
 
 fn foo(b: bool) -> Result<bool,String> {
     Err("bar".to_string());
-    //~^ ERROR type annotations or generic parameter binding required
+    //~^ ERROR unable to infer enough type information about `_` [E0282]
+    //~| NOTE cannot infer type for `_`
+    //~| NOTE type annotations or generic parameter binding
 }
 
 fn main() {
index c1f9dd6a4b8935a501acc71b898a311694592130..a64522a0e5b7543bfc038c051d3247a759a9088a 100644 (file)
@@ -17,7 +17,9 @@ pub fn foo<State>(_: TypeWithState<State>) {}
 
 pub fn bar() {
    foo(TypeWithState(marker::PhantomData));
-   //~^ ERROR type annotations or generic parameter binding required
+   //~^ ERROR unable to infer enough type information about `_` [E0282]
+   //~| NOTE cannot infer type for `_`
+   //~| NOTE type annotations or generic parameter binding
 }
 
 fn main() {
index 327fb6adf1d54f20374bff64a5e94c733c316003..e3cb1d0c7daafac93b6be3ec2842647bf4ca1e8c 100644 (file)
@@ -10,5 +10,7 @@
 
 fn main() {
     let v = &[];
-    let it = v.iter(); //~ ERROR type annotations or generic parameter binding required
+    let it = v.iter(); //~ ERROR unable to infer enough type information about `_` [E0282]
+                       //~| NOTE cannot infer type for `_`
+                       //~| NOTE type annotations or generic parameter binding
 }
index fe51d0b69987a5142775be84bf7f3b54364bcac4..d8ab48d1ec3e688cde39fe4a08c0592475764574 100644 (file)
 
 fn main() {
     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
-    //~^ ERROR attempted to divide with overflow
+    //~^ ERROR attempt to divide with overflow
     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
-    //~^ ERROR attempted to divide with overflow
+    //~^ ERROR attempt to divide with overflow
     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
-    //~^ ERROR attempted to divide with overflow
+    //~^ ERROR attempt to divide with overflow
     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
-    //~^ ERROR attempted to divide with overflow
+    //~^ ERROR attempt to divide with overflow
     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
-    //~^ ERROR attempted to divide with overflow
+    //~^ ERROR attempt to divide with overflow
     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
-    //~^ ERROR attempted to divide by zero
+    //~^ ERROR attempt to divide by zero
     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
-    //~^ ERROR attempted to divide by zero
+    //~^ ERROR attempt to divide by zero
     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
-    //~^ ERROR attempted to divide by zero
+    //~^ ERROR attempt to divide by zero
     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
-    //~^ ERROR attempted to divide by zero
+    //~^ ERROR attempt to divide by zero
     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
-    //~^ ERROR attempted to divide by zero
+    //~^ ERROR attempt to divide by zero
     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
-    //~^ ERROR attempted to calculate the remainder with overflow
+    //~^ ERROR attempt to calculate the remainder with overflow
     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
-    //~^ ERROR attempted to calculate the remainder with overflow
+    //~^ ERROR attempt to calculate the remainder with overflow
     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
-    //~^ ERROR attempted to calculate the remainder with overflow
+    //~^ ERROR attempt to calculate the remainder with overflow
     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
-    //~^ ERROR attempted to calculate the remainder with overflow
+    //~^ ERROR attempt to calculate the remainder with overflow
     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
-    //~^ ERROR attempted to calculate the remainder with overflow
+    //~^ ERROR attempt to calculate the remainder with overflow
     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
-    //~^ ERROR attempted to calculate the remainder with a divisor of zero
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
-    //~^ ERROR attempted to calculate the remainder with a divisor of zero
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
-    //~^ ERROR attempted to calculate the remainder with a divisor of zero
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
-    //~^ ERROR attempted to calculate the remainder with a divisor of zero
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
-    //~^ ERROR attempted to calculate the remainder with a divisor of zero
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
 }
index 6d5abc944e78f7dc2ca80ab94e150889c31897a1..3e51550d1fa07bc336bcb1da6f19545643e0674b 100644 (file)
@@ -53,7 +53,7 @@ fn main() {
       let n = n << 8; //~ ERROR: bitshift exceeds the type's number of bits
 
       let n = 1u8 << -8; //~ ERROR: bitshift exceeds the type's number of bits
-      //~^ WARN: attempted to shift by a negative amount
+      //~^ WARN: attempt to shift by a negative amount
 
       let n = 1u8 << (4+3);
       let n = 1u8 << (4+4); //~ ERROR: bitshift exceeds the type's number of bits
index e99dfb9aa0f0e9b6a425e6c9329ff3896feb9899..a2971f23a79e148a9a30a941d23ee2c9d68e4df7 100644 (file)
@@ -15,7 +15,7 @@
 #[allow(unused_variables)]
 fn main() {
     let x2: i8 = --128; //~ error: literal out of range for i8
-    //~^ error: attempted to negate with overflow
+    //~^ error: attempt to negate with overflow
 
     let x = -3.40282348e+38_f32; //~ error: literal out of range for f32
     let x =  3.40282348e+38_f32; //~ error: literal out of range for f32
index 40322f5a5b53b79f69c36a28fdde3e3c80ee7c6d..239f380e6c4abb6e0d673f26a153980e48eaea72 100644 (file)
@@ -79,6 +79,13 @@ fn f() {
     }
 }
 
+// c.f. issue #35135
+#[allow(unused_variables)]
+fn h() {
+    use test2::foo; //~ ERROR unused import
+    let foo = 0;
+}
+
 fn main() {
     cal(foo::Point{x:3, y:9});
     let mut a = 3;
index 59d75c5a787a6ec3815c66ee7473c8b776349f54..4f86909765ef1f84f0efd972291286990f8b9617 100644 (file)
@@ -32,7 +32,7 @@ fn foo(&self) -> isize {2}
 fn m1() {
     // we couldn't infer the type of the vector just based on calling foo()...
     let mut x = Vec::new();
-    //~^ ERROR type annotations or generic parameter binding required
+    //~^ ERROR unable to infer enough type information about `_` [E0282]
     x.foo();
 }
 
index 212c09364cf4c027c711e40e4f51f277052772bc..bcf676dbede6ff5bbd60c1cd209bc941de948936 100644 (file)
@@ -20,10 +20,13 @@ fn two(self, _: isize, _: isize) -> Foo { self }
 fn main() {
     let x = Foo;
     x.zero(0)   //~ ERROR this function takes 0 parameters but 1 parameter was supplied
+     //~^ NOTE expected 0 parameters
      .one()     //~ ERROR this function takes 1 parameter but 0 parameters were supplied
      //~^ NOTE the following parameter type was expected
+     //~| NOTE expected 1 parameter
      .two(0);   //~ ERROR this function takes 2 parameters but 1 parameter was supplied
      //~^ NOTE the following parameter types were expected
+     //~| NOTE expected 2 parameters
 
     let y = Foo;
     y.zero()
diff --git a/src/test/compile-fail/no-patterns-in-args.rs b/src/test/compile-fail/no-patterns-in-args.rs
new file mode 100644 (file)
index 0000000..3edbdf4
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern {
+    fn f1(mut arg: u8); //~ ERROR patterns aren't allowed in foreign function declarations
+                        //~^ NOTE this is a recent error
+    fn f2(&arg: u8); //~ ERROR patterns aren't allowed in foreign function declarations
+    fn f3(arg @ _: u8); //~ ERROR patterns aren't allowed in foreign function declarations
+                        //~^ NOTE this is a recent error
+    fn g1(arg: u8); // OK
+    fn g2(_: u8); // OK
+    // fn g3(u8); // Not yet
+}
+
+type A1 = fn(mut arg: u8); //~ ERROR patterns aren't allowed in function pointer types
+                           //~^ NOTE this is a recent error
+type A2 = fn(&arg: u8); //~ ERROR patterns aren't allowed in function pointer types
+                        //~^ NOTE this is a recent error
+type B1 = fn(arg: u8); // OK
+type B2 = fn(_: u8); // OK
+type B3 = fn(u8); // OK
+
+fn main() {}
index 0b12a9acbcb9e9d56de662b81d4234bda7fc35a7..eba61ede8cb20e673e945fbe6c19e8c6043f0422 100644 (file)
@@ -19,6 +19,7 @@ struct Foo {
 fn struct_with_a_nested_enum_and_vector() {
     match (Foo { first: true, second: None }) {
 //~^ ERROR non-exhaustive patterns: `Foo { first: false, second: Some([_, _, _, _]) }` not covered
+//~| NOTE pattern `Foo { first: false, second: Some([_, _, _, _]) }` not covered
         Foo { first: true, second: None } => (),
         Foo { first: true, second: Some(_) } => (),
         Foo { first: false, second: None } => (),
@@ -35,6 +36,7 @@ enum Color {
 fn enum_with_single_missing_variant() {
     match Color::Red {
     //~^ ERROR non-exhaustive patterns: `Red` not covered
+    //~| NOTE pattern `Red` not covered
         Color::CustomRGBA { .. } => (),
         Color::Green => ()
     }
@@ -47,6 +49,7 @@ enum Direction {
 fn enum_with_multiple_missing_variants() {
     match Direction::North {
     //~^ ERROR non-exhaustive patterns: `East`, `South` and `West` not covered
+    //~| NOTE patterns `East`, `South` and `West` not covered
         Direction::North => ()
     }
 }
@@ -58,6 +61,7 @@ enum ExcessiveEnum {
 fn enum_with_excessive_missing_variants() {
     match ExcessiveEnum::First {
     //~^ ERROR `Second`, `Third`, `Fourth` and 8 more not covered
+    //~| NOTE patterns `Second`, `Third`, `Fourth` and 8 more not covered
 
         ExcessiveEnum::First => ()
     }
@@ -66,6 +70,7 @@ fn enum_with_excessive_missing_variants() {
 fn enum_struct_variant() {
     match Color::Red {
     //~^ ERROR non-exhaustive patterns: `CustomRGBA { a: true, .. }` not covered
+    //~| NOTE pattern `CustomRGBA { a: true, .. }` not covered
         Color::Red => (),
         Color::Green => (),
         Color::CustomRGBA { a: false, r: _, g: _, b: 0 } => (),
@@ -82,6 +87,7 @@ fn vectors_with_nested_enums() {
     let x: &'static [Enum] = &[Enum::First, Enum::Second(false)];
     match *x {
     //~^ ERROR non-exhaustive patterns: `[Second(true), Second(false)]` not covered
+    //~| NOTE pattern `[Second(true), Second(false)]` not covered
         [] => (),
         [_] => (),
         [Enum::First, _] => (),
@@ -95,6 +101,7 @@ fn vectors_with_nested_enums() {
 fn missing_nil() {
     match ((), false) {
     //~^ ERROR non-exhaustive patterns: `((), false)` not covered
+    //~| NOTE pattern `((), false)` not covered
         ((), true) => ()
     }
 }
index 1f5a54477dd6d0fa83f4597179b819deec94c5db..f2f61fcaeec16d5fdd97b11c8243ecf8209cbdb3 100644 (file)
@@ -19,5 +19,6 @@ fn foo(a: isize, b: isize, c: isize, d:isize) {
 fn main() {
   foo(1, 2, 3);
   //~^ ERROR this function takes 4 parameters but 3
-  //~^^ NOTE the following parameter types were expected
+  //~| NOTE the following parameter types were expected
+  //~| NOTE expected 4 parameters
 }
index 8763fb0913a87287ef21d84b391dc7be7bc6bf68..5865d93e1282ffdbe28e397fa7bf4e93f8438996 100644 (file)
@@ -42,7 +42,9 @@ fn main() {
     let ans = s();
     //~^ ERROR this function takes 1 parameter but 0 parameters were supplied
     //~| NOTE the following parameter type was expected
+    //~| NOTE expected 1 parameter
     let ans = s("burma", "shave");
     //~^ ERROR this function takes 1 parameter but 2 parameters were supplied
     //~| NOTE the following parameter type was expected
+    //~| NOTE expected 1 parameter
 }
index 5c661bfcdc0c99c99d0c248d40280b72246fc33c..e685ebc272098b1264366b8a59b0905305a4829e 100644 (file)
@@ -25,7 +25,11 @@ impl S {
     fn f<T>() {}
 }
 
-type A = <S as Tr>::A::f<u8>; //~ ERROR type parameters are not allowed on this type
-//~^ ERROR ambiguous associated type; specify the type using the syntax `<<S as Tr>::A as Trait>::f`
+type A = <S as Tr>::A::f<u8>;
+//~^ ERROR type parameters are not allowed on this type
+//~| NOTE type parameter not allowed
+//~| ERROR ambiguous associated type
+//~| NOTE ambiguous associated type
+//~| NOTE specify the type using the syntax `<<S as Tr>::A as Trait>::f`
 
 fn main() {}
index 4fda8ec3f384ebaa2185e6c365d1bbefd54730be..6be2adbe2a0d1ac0eb200159b11af647bc1f875b 100644 (file)
 
 fn escaping_borrow_of_closure_params_1() {
     let g = |x: usize, y:usize| {
+        //~^ NOTE reference must be valid for the scope of call-site for function
+        //~| NOTE ...but borrowed value is only valid for the scope of function body
+        //~| NOTE reference must be valid for the scope of call-site for function
+        //~| NOTE ...but borrowed value is only valid for the scope of function body
         let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
         //~^ ERROR `x` does not live long enough
         //~| ERROR `y` does not live long enough
@@ -31,6 +35,10 @@ fn escaping_borrow_of_closure_params_1() {
 
 fn escaping_borrow_of_closure_params_2() {
     let g = |x: usize, y:usize| {
+        //~^ NOTE reference must be valid for the scope of call-site for function
+        //~| NOTE ...but borrowed value is only valid for the scope of function body
+        //~| NOTE reference must be valid for the scope of call-site for function
+        //~| NOTE ...but borrowed value is only valid for the scope of function body
         let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
         //~^ ERROR `x` does not live long enough
         //~| ERROR `y` does not live long enough
@@ -64,7 +72,11 @@ fn escaping_borrow_of_fn_params_1() {
     fn g<'a>(x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
         let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
         //~^ ERROR E0373
+        //~| NOTE `x` is borrowed here
+        //~| NOTE may outlive borrowed value `x`
         //~| ERROR E0373
+        //~| NOTE `y` is borrowed here
+        //~| NOTE may outlive borrowed value `y`
         return Box::new(f);
     };
 
@@ -75,7 +87,11 @@ fn escaping_borrow_of_fn_params_2() {
     fn g<'a>(x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
         let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
         //~^ ERROR E0373
+        //~| NOTE `x` is borrowed here
+        //~| NOTE may outlive borrowed value `x`
         //~| ERROR E0373
+        //~| NOTE `y` is borrowed here
+        //~| NOTE may outlive borrowed value `y`
         Box::new(f)
     };
 
@@ -99,7 +115,11 @@ impl S {
         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
             //~^ ERROR E0373
+            //~| NOTE `x` is borrowed here
+            //~| NOTE may outlive borrowed value `x`
             //~| ERROR E0373
+            //~| NOTE `y` is borrowed here
+            //~| NOTE may outlive borrowed value `y`
             return Box::new(f);
         }
     }
@@ -113,7 +133,11 @@ impl S {
         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
             //~^ ERROR E0373
+            //~| NOTE `x` is borrowed here
+            //~| NOTE may outlive borrowed value `x`
             //~| ERROR E0373
+            //~| NOTE `y` is borrowed here
+            //~| NOTE may outlive borrowed value `y`
             Box::new(f)
         }
     }
@@ -141,7 +165,11 @@ impl T for S {
         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
             //~^ ERROR E0373
+            //~| NOTE `x` is borrowed here
+            //~| NOTE may outlive borrowed value `x`
             //~| ERROR E0373
+            //~| NOTE `y` is borrowed here
+            //~| NOTE may outlive borrowed value `y`
             return Box::new(f);
         }
     }
@@ -156,7 +184,11 @@ impl T for S {
         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
             //~^ ERROR E0373
+            //~| NOTE `x` is borrowed here
+            //~| NOTE may outlive borrowed value `x`
             //~| ERROR E0373
+            //~| NOTE `y` is borrowed here
+            //~| NOTE may outlive borrowed value `y`
             Box::new(f)
         }
     }
@@ -184,7 +216,11 @@ trait T {
         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
             //~^ ERROR E0373
+            //~| NOTE `x` is borrowed here
+            //~| NOTE may outlive borrowed value `x`
             //~| ERROR E0373
+            //~| NOTE `y` is borrowed here
+            //~| NOTE may outlive borrowed value `y`
             return Box::new(f);
         }
     }
@@ -198,7 +234,11 @@ trait T {
         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
             //~^ ERROR E0373
+            //~| NOTE `x` is borrowed here
+            //~| NOTE may outlive borrowed value `x`
             //~| ERROR E0373
+            //~| NOTE `y` is borrowed here
+            //~| NOTE may outlive borrowed value `y`
             Box::new(f)
         }
     }
index 948dc8cd219689301a9b30ba2702422a39294451..40ba34b26ede673a1c0fb4f88e34f3d8b68e627e 100644 (file)
@@ -13,8 +13,11 @@ fn ignore<F>(_f: F) where F: for<'z> FnOnce(&'z isize) -> &'z isize {}
 fn nested() {
     let y = 3;
     ignore(
-        |z| { //~ ERROR E0373
+        |z| {
+            //~^ ERROR E0373
+            //~| NOTE may outlive borrowed value `y`
             if false { &y } else { z }
+            //~^ NOTE `y` is borrowed here
         });
 }
 
index 1758b28a32482555bb6911420f996ced91ed6330..555dd0f0c3945fd52c15de1690550b973f2cb1e7 100644 (file)
@@ -20,23 +20,27 @@ fn main() {
     //~| expected type `usize`
     //~| found type `()`
     //~| expected usize, found ()
-    //~| ERROR expected usize for repeat count, found tuple [E0306]
+    //~| ERROR expected `usize` for repeat count, found tuple [E0306]
+    //~| expected `usize`
     let c = [0; true];
     //~^ ERROR mismatched types
     //~| expected usize, found bool
-    //~| ERROR expected usize for repeat count, found boolean [E0306]
+    //~| ERROR expected `usize` for repeat count, found boolean [E0306]
+    //~| expected `usize`
     let d = [0; 0.5];
     //~^ ERROR mismatched types
     //~| expected type `usize`
     //~| found type `{float}`
     //~| expected usize, found floating-point variable
-    //~| ERROR expected usize for repeat count, found float [E0306]
+    //~| ERROR expected `usize` for repeat count, found float [E0306]
+    //~| expected `usize`
     let e = [0; "foo"];
     //~^ ERROR mismatched types
     //~| expected type `usize`
     //~| found type `&'static str`
     //~| expected usize, found &-ptr
-    //~| ERROR expected usize for repeat count, found string literal [E0306]
+    //~| ERROR expected `usize` for repeat count, found string literal [E0306]
+    //~| expected `usize`
     let f = [0; -4_isize];
     //~^ ERROR constant evaluation error
     //~| expected usize, found isize
@@ -55,5 +59,6 @@ struct G {
     //~| expected type `usize`
     //~| found type `main::G`
     //~| expected usize, found struct `main::G`
-    //~| ERROR expected usize for repeat count, found struct [E0306]
+    //~| ERROR expected `usize` for repeat count, found struct [E0306]
+    //~| expected `usize`
 }
index d058c6a5a3b93fbb6c6bf3f6d232d8e9fdc0806f..860e69fcaec4d46b6f0b43d12d17f4adc0ef8989 100644 (file)
@@ -31,9 +31,13 @@ impl SuperFoo for Bar {
 impl Bar {
     fn f() {
         let _: <Self>::Baz = true;
-//~^ERROR: ambiguous associated type; specify the type using the syntax `<Bar as Trait>::Baz`
+        //~^ ERROR ambiguous associated type
+        //~| NOTE ambiguous associated type
+        //~| NOTE specify the type using the syntax `<Bar as Trait>::Baz`
         let _: Self::Baz = true;
-//~^ERROR: ambiguous associated type; specify the type using the syntax `<Bar as Trait>::Baz`
+        //~^ ERROR ambiguous associated type
+        //~| NOTE ambiguous associated type
+        //~| NOTE specify the type using the syntax `<Bar as Trait>::Baz`
     }
 }
 
index 049569e8a184fb3aa68ea428bdcac0a67ff0ff80..dd9d7d29468825eb56d6f32e64fd7c5cf5f0613b 100644 (file)
@@ -9,8 +9,10 @@
 // except according to those terms.
 
 struct BuildData {
+    foo: isize, //~ NOTE `foo` first declared here
     foo: isize,
-    foo: isize, //~ ERROR field `foo` is already declared
+    //~^ ERROR field `foo` is already declared [E0124]
+    //~| NOTE field already declared
 }
 
 fn main() {
index 13fdaa302f70a72ee0a800f21b42a93de4c9050d..c78eebddbfdb80051d8b5be9a4150f51df653000 100644 (file)
@@ -13,4 +13,5 @@ trait TraitNotAStruct {}
 fn main() {
     TraitNotAStruct{ value: 0 };
     //~^ ERROR: `TraitNotAStruct` does not name a struct or a struct variant [E0071]
+    //~| NOTE not a struct
 }
index c77494912bc751fc1715fb9de7544bffe274131b..e6545063dbd4414e4a246986693933f4751bbe3a 100644 (file)
@@ -34,7 +34,9 @@ fn test<T,U>(_: T, _: U)
 
 fn a() {
     test(22, std::default::Default::default());
-    //~^ ERROR type annotations or generic parameter binding required
+    //~^ ERROR unable to infer enough type information about `_` [E0282]
+    //~| NOTE cannot infer type for `_`
+    //~| NOTE type annotations or generic parameter binding
 }
 
 fn main() {}
index fb6c43a19059a42885a94ada94ab2f894e54dd1a..41242a44f58b80c1c852473ca2c8bbf39d38e4e2 100644 (file)
@@ -9,20 +9,27 @@
 // except according to those terms.
 
 fn foo1<T:Copy<U>, U>(x: T) {}
-//~^ ERROR: wrong number of type arguments: expected 0, found 1
+//~^ ERROR E0244
+//~| NOTE expected no type arguments, found 1
 
 trait Trait: Copy<Send> {}
-//~^ ERROR: wrong number of type arguments: expected 0, found 1
+//~^ ERROR E0244
+//~| NOTE expected no type arguments, found 1
 
 struct MyStruct1<T: Copy<T>>;
-//~^ ERROR wrong number of type arguments: expected 0, found 1
+//~^ ERROR E0244
+//~| NOTE expected no type arguments, found 1
 
 struct MyStruct2<'a, T: Copy<'a>>;
 //~^ ERROR: wrong number of lifetime parameters: expected 0, found 1
+//~| NOTE unexpected lifetime parameter
+
 
 fn foo2<'a, T:Copy<'a, U>, U>(x: T) {}
-//~^ ERROR: wrong number of type arguments: expected 0, found 1
-//~^^ ERROR: wrong number of lifetime parameters: expected 0, found 1
+//~^ ERROR E0244
+//~| NOTE expected no type arguments, found 1
+//~| ERROR: wrong number of lifetime parameters: expected 0, found 1
+//~| NOTE unexpected lifetime parameter
 
 fn main() {
 }
index d4f3cdfd8b7e248eefedc4d3896d13a0101ff235..42db3b47a04f3af15e6c3faf07ed8e2107a9b528 100644 (file)
 
 fn test() -> _ { 5 }
 //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+//~| NOTE not allowed in type signatures
 
 fn test2() -> (_, _) { (5, 5) }
 //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
 //~^^ ERROR the type placeholder `_` is not allowed within types on item signatures
+//~| NOTE not allowed in type signatures
+//~| NOTE not allowed in type signatures
 
 static TEST3: _ = "test";
 //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+//~| NOTE not allowed in type signatures
 
 static TEST4: _ = 145;
 //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+//~| NOTE not allowed in type signatures
 
 static TEST5: (_, _) = (1, 2);
 //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
 //~^^ ERROR the type placeholder `_` is not allowed within types on item signatures
+//~| NOTE not allowed in type signatures
+//~| NOTE not allowed in type signatures
 
 fn test6(_: _) { }
 //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+//~| NOTE not allowed in type signatures
 
 fn test7(x: _) { let _x: usize = x; }
 //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+//~| NOTE not allowed in type signatures
 
 fn test8(_f: fn() -> _) { }
 //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+//~| NOTE not allowed in type signatures
 
 struct Test9;
 
 impl Test9 {
     fn test9(&self) -> _ { () }
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+    //~| NOTE not allowed in type signatures
 
     fn test10(&self, _x : _) { }
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+    //~| NOTE not allowed in type signatures
 }
 
 impl Clone for Test9 {
     fn clone(&self) -> _ { Test9 }
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+    //~| NOTE not allowed in type signatures
 
     fn clone_from(&mut self, other: _) { *self = Test9; }
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+    //~| NOTE not allowed in type signatures
 }
 
 struct Test10 {
     a: _,
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+    //~| NOTE not allowed in type signatures
     b: (_, _),
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
     //~^^ ERROR the type placeholder `_` is not allowed within types on item signatures
+    //~| NOTE not allowed in type signatures
+    //~| NOTE not allowed in type signatures
 }
 
 pub fn main() {
     fn fn_test() -> _ { 5 }
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+    //~| NOTE not allowed in type signatures
 
     fn fn_test2() -> (_, _) { (5, 5) }
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
     //~^^ ERROR the type placeholder `_` is not allowed within types on item signatures
+    //~| NOTE not allowed in type signatures
+    //~| NOTE not allowed in type signatures
 
     static FN_TEST3: _ = "test";
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+    //~| NOTE not allowed in type signatures
 
     static FN_TEST4: _ = 145;
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+    //~| NOTE not allowed in type signatures
 
     static FN_TEST5: (_, _) = (1, 2);
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
     //~^^ ERROR the type placeholder `_` is not allowed within types on item signatures
+    //~| NOTE not allowed in type signatures
+    //~| NOTE not allowed in type signatures
 
     fn fn_test6(_: _) { }
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+    //~| NOTE not allowed in type signatures
 
     fn fn_test7(x: _) { let _x: usize = x; }
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+    //~| NOTE not allowed in type signatures
 
     fn fn_test8(_f: fn() -> _) { }
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+    //~| NOTE not allowed in type signatures
 
     struct FnTest9;
 
     impl FnTest9 {
         fn fn_test9(&self) -> _ { () }
         //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+        //~| NOTE not allowed in type signatures
 
         fn fn_test10(&self, _x : _) { }
         //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+        //~| NOTE not allowed in type signatures
     }
 
     impl Clone for FnTest9 {
         fn clone(&self) -> _ { FnTest9 }
         //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+        //~| NOTE not allowed in type signatures
 
         fn clone_from(&mut self, other: _) { *self = FnTest9; }
         //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+        //~| NOTE not allowed in type signatures
     }
 
     struct FnTest10 {
         a: _,
         //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+        //~| NOTE not allowed in type signatures
         b: (_, _),
         //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
         //~^^ ERROR the type placeholder `_` is not allowed within types on item signatures
+        //~| NOTE not allowed in type signatures
+        //~| NOTE not allowed in type signatures
     }
 
 }
index 2cb46cc352beca366f166325584e56cfecc78199..f60d925a74864b918978de7a9ecc12ed9d8f4663 100644 (file)
@@ -17,5 +17,6 @@ struct Foo<'a, T:'a> {
 
 pub fn main() {
     let c: Foo<_, _> = Foo { r: &5 };
-    //~^ ERROR wrong number of type arguments: expected 1, found 2
+    //~^ ERROR E0244
+    //~| NOTE expected 1 type arguments, found 2
 }
index 8178335de5931a21d590311714e36a5bb6a65fbf..ec2675ece74b0dea088c6325650d63c22dd86682 100644 (file)
@@ -17,5 +17,6 @@ struct Foo<'a, T:'a> {
 
 pub fn main() {
     let c: Foo<_, usize> = Foo { r: &5 };
-    //~^ ERROR wrong number of type arguments: expected 1, found 2
+    //~^ ERROR E0244
+    //~| NOTE expected 1 type arguments, found 2
 }
index 04bbfc445edeaab920911845a249d8f4a30d7220..1209757610251cd8477b890325a24bdaf7727b2a 100644 (file)
@@ -13,7 +13,8 @@
 trait Trait {}
 
 fn f<F:Trait(isize) -> isize>(x: F) {}
-//~^ ERROR wrong number of type arguments: expected 0, found 1
+//~^ ERROR E0244
+//~| NOTE expected no type arguments, found 1
 //~| ERROR associated type `Output` not found
 
 fn main() {}
index c14de98e03f14ab6b7bfc3539c8888cb06e750d2..380cdd266cd6e86eff564624814a54a7586148c2 100644 (file)
@@ -11,5 +11,7 @@
 // Issue #5062
 
 fn main() {
-    None; //~ ERROR type annotations or generic parameter binding required
+    None; //~ ERROR unable to infer enough type information about `_` [E0282]
+          //~| NOTE cannot infer type for `_`
+          //~| NOTE type annotations or generic parameter binding
 }
index 02a3f2b9ab8d28ad31faceed2344b574ade04563..ba94bf613d217d8e18c3ff27775e91b2a82185ee 100644 (file)
@@ -13,5 +13,7 @@ struct S<'a, T:'a> {
 }
 
 fn main() {
-    S { o: &None }; //~ ERROR type annotations or generic parameter binding required
+    S { o: &None }; //~ ERROR unable to infer enough type information about `_` [E0282]
+                    //~| NOTE cannot infer type for `_`
+                    //~| NOTE type annotations or generic parameter binding
 }
index bbb063770c148274fd1ee99df28074b7f544c446..6be878dce1fb93acb3acc874225b9169582997aa 100644 (file)
@@ -15,7 +15,8 @@
     Bar,
     self
 //~^ NOTE another `self` import appears here
-//~^^ ERROR a module named `bar` has already been imported in this module
+//~| ERROR a module named `bar` has already been imported in this module
+//~| NOTE already imported
 };
 
 use {self};
index d8620ead836397d8a290c961cfb38c939913f047..cc9a7c84eded46c495a185350591a4b48382d53a 100644 (file)
@@ -18,8 +18,10 @@ fn main() {
     unsafe {
         foo(); //~ ERROR: this function takes at least 2 parameters but 0 parameters were supplied
         //~^ NOTE the following parameter types were expected
+        //~| NOTE expected at least 2 parameters
         foo(1); //~ ERROR: this function takes at least 2 parameters but 1 parameter was supplied
         //~^ NOTE the following parameter types were expected
+        //~| NOTE expected at least 2 parameters
 
         let x: unsafe extern "C" fn(f: isize, x: u8) = foo;
         //~^ ERROR: mismatched types
index 419b8c4e1b0151847753672e2b21eba3ee067309..25709f35246e3b37f70ae690f6869b133718bbc0 100644 (file)
@@ -11,5 +11,7 @@
 
 fn main() {
     let _foo = Vec::new();
-    //~^ ERROR type annotations or generic parameter binding required
+    //~^ ERROR unable to infer enough type information about `_` [E0282]
+    //~| NOTE cannot infer type for `_`
+    //~| NOTE type annotations or generic parameter binding
 }
diff --git a/src/test/mir-opt/deaggregator_test.rs b/src/test/mir-opt/deaggregator_test.rs
new file mode 100644 (file)
index 0000000..e57a967
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Baz {
+    x: usize,
+    y: f32,
+    z: bool,
+}
+
+fn bar(a: usize) -> Baz {
+    Baz { x: a, y: 0.0, z: false }
+}
+
+fn main() {}
+
+// END RUST SOURCE
+// START rustc.node13.Deaggregator.before.mir
+// bb0: {
+//     var0 = arg0;                     // scope 0 at main.rs:8:8: 8:9
+//     tmp0 = var0;                     // scope 1 at main.rs:9:14: 9:15
+//     return = Baz { x: tmp0, y: const F32(0), z: const false }; // scope ...
+//     goto -> bb1;                     // scope 1 at main.rs:8:1: 10:2
+// }
+// END rustc.node13.Deaggregator.before.mir
+// START rustc.node13.Deaggregator.after.mir
+// bb0: {
+//     var0 = arg0;                     // scope 0 at main.rs:8:8: 8:9
+//     tmp0 = var0;                     // scope 1 at main.rs:9:14: 9:15
+//     (return.0: usize) = tmp0;        // scope 1 at main.rs:9:5: 9:34
+//     (return.1: f32) = const F32(0);  // scope 1 at main.rs:9:5: 9:34
+//     (return.2: bool) = const false;  // scope 1 at main.rs:9:5: 9:34
+//     goto -> bb1;                     // scope 1 at main.rs:8:1: 10:2
+// }
+// END rustc.node13.Deaggregator.after.mir
\ No newline at end of file
index 3d9bee3c86a569fe8bc6691925afa1c04e2c3cd1..c9c4a88c9b53eca1692726f0990cb833a5c7cf0f 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty : (#23623) problems when  ending with // comments
 
-// error-pattern:attempted to divide by zero
+// error-pattern:attempt to divide by zero
 
 fn main() {
     let y = 0;
index 686c3eb2f83b860ad66b29eb85cd439463973289..d2b598a7933bcd86f128cbffdd484c5a83d3ee52 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty : (#23623) problems when  ending with // comments
 
-// error-pattern:attempted to calculate the remainder with a divisor of zero
+// error-pattern:attempt to calculate the remainder with a divisor of zero
 
 fn main() {
     let y = 0;
index ecb8c676cf700d689cda252865747949a14bc3f5..acc7676db457efd8d71c8264b37acd7b989562cd 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty : (#23623) problems when  ending with // comments
 
-// error-pattern:thread 'main' panicked at 'attempted to add with overflow'
+// error-pattern:thread 'main' panicked at 'attempt to add with overflow'
 // compile-flags: -C debug-assertions
 
 
index e277886d003dce43e3ea65bc456386b109158061..29ce3b0e6a16d7be8eb6fb2479fdd9b72b06baf3 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty : (#23623) problems when  ending with // comments
 
-// error-pattern:thread 'main' panicked at 'attempted to shift left with overflow'
+// error-pattern:thread 'main' panicked at 'attempt to shift left with overflow'
 // compile-flags: -C debug-assertions
 
 #![warn(exceeding_bitshifts)]
index 42cb0f2d55bc1ba90c2a1223c995ad3d2bed71a5..62fc9230f353d07f2f8426d86b349416391df3a0 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty : (#23623) problems when  ending with // comments
 
-// error-pattern:thread 'main' panicked at 'attempted to shift left with overflow'
+// error-pattern:thread 'main' panicked at 'attempt to shift left with overflow'
 // compile-flags: -C debug-assertions
 
 #![warn(exceeding_bitshifts)]
index 8c6623dcf50ceeff50c1225bbf6e54c0013f47f2..1bc1703a89ce37702c59c1436c03c5fb5d259e40 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty : (#23623) problems when  ending with // comments
 
-// error-pattern:thread 'main' panicked at 'attempted to shift left with overflow'
+// error-pattern:thread 'main' panicked at 'attempt to shift left with overflow'
 // compile-flags: -C debug-assertions
 
 #![warn(exceeding_bitshifts)]
index 3b7a00a2c73c6dd3cba02828e4bdec4b19428f32..8de44f25e048967ec0d732654dcdf3ad8d718216 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty : (#23623) problems when  ending with // comments
 
-// error-pattern:thread 'main' panicked at 'attempted to shift left with overflow'
+// error-pattern:thread 'main' panicked at 'attempt to shift left with overflow'
 // compile-flags: -C debug-assertions
 
 // This function is checking that our automatic truncation does not
index 0e168bf6ffbc6e3c60b8ec0e60438b472c344a6a..a09c0f06a5cc6180f383100d8bf289ba20d7e076 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty : (#23623) problems when  ending with // comments
 
-// error-pattern:thread 'main' panicked at 'attempted to multiply with overflow'
+// error-pattern:thread 'main' panicked at 'attempt to multiply with overflow'
 // compile-flags: -C debug-assertions
 
 fn main() {
index 84e41ea848809b2ff82637112cba4e0682879500..96853fc565b716d4511d014f1e98b613833f7cd4 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty : (#23623) problems when  ending with // comments
 
-// error-pattern:thread 'main' panicked at 'attempted to negate with overflow'
+// error-pattern:thread 'main' panicked at 'attempt to negate with overflow'
 // compile-flags: -C debug-assertions
 
 fn main() {
index 9172374ec2818b41e7a1a2e48b7de662271eef68..b0ff0df557704f41ad42c9856c90217461959841 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:thread 'main' panicked at 'attempted to multiply with overflow'
+// error-pattern:thread 'main' panicked at 'attempt to multiply with overflow'
 // compile-flags: -C debug-assertions
 
 fn main() {
index d275792485d5126851e89d77f94714d86f2df4b1..ef4a503cfe42592d3674c2e479d714f7187a105b 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty : (#23623) problems when  ending with // comments
 
-// error-pattern:thread 'main' panicked at 'attempted to shift right with overflow'
+// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
 // compile-flags: -C debug-assertions
 
 #![warn(exceeding_bitshifts)]
index 1b888cddf64436a9e7ffe5ea54e33b0512adacdd..da072b5a9a5a999c39cd535109d51fd4126139c0 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty : (#23623) problems when  ending with // comments
 
-// error-pattern:thread 'main' panicked at 'attempted to shift right with overflow'
+// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
 // compile-flags: -C debug-assertions
 
 #![warn(exceeding_bitshifts)]
index be5c213493d6dbb90dfa2d2489d127f17920e033..0b7809402e6db93222cc588bf1dfc1b8c4d590e1 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty : (#23623) problems when  ending with // comments
 
-// error-pattern:thread 'main' panicked at 'attempted to shift right with overflow'
+// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
 // compile-flags: -C debug-assertions
 
 #![warn(exceeding_bitshifts)]
index 820d9611d6acb973922b2cf36fadb603dd136612..1e0cc18fbdcd63c9fb9e01a3ffac16f43a229240 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty : (#23623) problems when  ending with // comments
 
-// error-pattern:thread 'main' panicked at 'attempted to shift right with overflow'
+// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
 // compile-flags: -C debug-assertions
 
 // This function is checking that our (type-based) automatic
index b87be696fcb213ba699d2715985a990b30b567d1..690901ff0c25b0f95d855604e3fe7cef932466d8 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty : (#23623) problems when  ending with // comments
 
-// error-pattern:thread 'main' panicked at 'attempted to shift right with overflow'
+// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
 // compile-flags: -C debug-assertions
 
 #![warn(exceeding_bitshifts)]
index 554675686b5e293d80b54f9bb905d112ffe10f61..6a6ed4f11f20ef3dc7711d832bad80e2c32f964f 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty : (#23623) problems when  ending with // comments
 
-// error-pattern:thread 'main' panicked at 'attempted to shift right with overflow'
+// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
 // compile-flags: -C debug-assertions
 
 #![warn(exceeding_bitshifts)]
index 1cb207240ca492e2b8185733e7a51ae136d701a2..083e8d24467fd67148a2d7bff94c5182413adb33 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty : (#23623) problems when  ending with // comments
 
-// error-pattern:thread 'main' panicked at 'attempted to subtract with overflow'
+// error-pattern:thread 'main' panicked at 'attempt to subtract with overflow'
 // compile-flags: -C debug-assertions
 
 fn main() {
index 388d3238d4248960c37b2a317d249fca570f5a69..42c0da6286bdca27f95692cd6b85c074ac6cc569 100644 (file)
 pub type F = Option<isize>;
 pub type G = usize;
 pub type H = &'static str;
+pub type I = Box<Fn()>;
 
-pub unsafe fn id_A() -> TypeId { TypeId::of::<A>() }
-pub unsafe fn id_B() -> TypeId { TypeId::of::<B>() }
-pub unsafe fn id_C() -> TypeId { TypeId::of::<C>() }
-pub unsafe fn id_D() -> TypeId { TypeId::of::<D>() }
-pub unsafe fn id_E() -> TypeId { TypeId::of::<E>() }
-pub unsafe fn id_F() -> TypeId { TypeId::of::<F>() }
-pub unsafe fn id_G() -> TypeId { TypeId::of::<G>() }
-pub unsafe fn id_H() -> TypeId { TypeId::of::<H>() }
+pub fn id_A() -> TypeId { TypeId::of::<A>() }
+pub fn id_B() -> TypeId { TypeId::of::<B>() }
+pub fn id_C() -> TypeId { TypeId::of::<C>() }
+pub fn id_D() -> TypeId { TypeId::of::<D>() }
+pub fn id_E() -> TypeId { TypeId::of::<E>() }
+pub fn id_F() -> TypeId { TypeId::of::<F>() }
+pub fn id_G() -> TypeId { TypeId::of::<G>() }
+pub fn id_H() -> TypeId { TypeId::of::<H>() }
+pub fn id_I() -> TypeId { TypeId::of::<I>() }
 
-pub unsafe fn foo<T: Any>() -> TypeId { TypeId::of::<T>() }
+pub fn foo<T: Any>() -> TypeId { TypeId::of::<T>() }
index 3ad307fd3b507b6b3cf199b4abb946227c881beb..42c0da6286bdca27f95692cd6b85c074ac6cc569 100644 (file)
 pub type F = Option<isize>;
 pub type G = usize;
 pub type H = &'static str;
+pub type I = Box<Fn()>;
 
-pub unsafe fn id_A() -> TypeId { TypeId::of::<A>() }
-pub unsafe fn id_B() -> TypeId { TypeId::of::<B>() }
-pub unsafe fn id_C() -> TypeId { TypeId::of::<C>() }
-pub unsafe fn id_D() -> TypeId { TypeId::of::<D>() }
-pub unsafe fn id_E() -> TypeId { TypeId::of::<E>() }
-pub unsafe fn id_F() -> TypeId { TypeId::of::<F>() }
-pub unsafe fn id_G() -> TypeId { TypeId::of::<G>() }
-pub unsafe fn id_H() -> TypeId { TypeId::of::<H>() }
+pub fn id_A() -> TypeId { TypeId::of::<A>() }
+pub fn id_B() -> TypeId { TypeId::of::<B>() }
+pub fn id_C() -> TypeId { TypeId::of::<C>() }
+pub fn id_D() -> TypeId { TypeId::of::<D>() }
+pub fn id_E() -> TypeId { TypeId::of::<E>() }
+pub fn id_F() -> TypeId { TypeId::of::<F>() }
+pub fn id_G() -> TypeId { TypeId::of::<G>() }
+pub fn id_H() -> TypeId { TypeId::of::<H>() }
+pub fn id_I() -> TypeId { TypeId::of::<I>() }
 
-pub unsafe fn foo<T:Any>() -> TypeId { TypeId::of::<T>() }
+pub fn foo<T: Any>() -> TypeId { TypeId::of::<T>() }
index 5f8e7cb8145e6a63e409a28cba10b213c8cf3e15..428d4e4dbb12de1d80018cc9632b7b64e0d4ec9d 100644 (file)
@@ -28,7 +28,8 @@ macro_rules! demo {
             unsafe {
                 asm!("mov ($1), $0"
                      : $output_constraint (*wrap(&mut x, "out", &mut history))
-                     : "r"(&wrap(y, "in", &mut history)));
+                     : "r"(&wrap(y, "in", &mut history))
+                     :: "volatile");
             }
             assert_eq!((x,y), (1,1));
             let b: &[_] = &["out", "in"];
diff --git a/src/test/run-pass/issue-20847.rs b/src/test/run-pass/issue-20847.rs
new file mode 100644 (file)
index 0000000..d2c3356
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(fn_traits)]
+
+use std::ops::Fn;
+
+fn say(x: u32, y: u32) {
+    println!("{} {}", x, y);
+}
+
+fn main() {
+    Fn::call(&say, (1, 2));
+}
index f01ce46a891d9f6ce220a64e64bb804ba8c6bd02..efce148ea51d487f851e4bdab84c4dd1d45eca52 100644 (file)
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-flags: -Z orbit=off
+// (blows the stack with MIR trans and no optimizations)
+
 // Tests that the `vec!` macro does not overflow the stack when it is
 // given data larger than the stack.
 
diff --git a/src/test/run-pass/mir_cross_crate.rs b/src/test/run-pass/mir_cross_crate.rs
new file mode 100644 (file)
index 0000000..cc239d9
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -Z orbit
+// Tests that -Z orbit affects functions from other crates.
+
+#![feature(unsafe_no_drop_flag)]
+
+#[unsafe_no_drop_flag]
+struct Foo;
+
+impl Drop for Foo {
+    fn drop(&mut self) {
+        panic!("MIR trans is not enabled for mem::forget");
+    }
+}
+
+fn main() {
+    let x = Foo;
+    std::mem::forget(x);
+}
diff --git a/src/test/run-pass/mir_overflow_off.rs b/src/test/run-pass/mir_overflow_off.rs
new file mode 100644 (file)
index 0000000..04ac606
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -Z force-overflow-checks=off -Z orbit
+
+// Test that with MIR trans, overflow checks can be
+// turned off, even when they're from core::ops::*.
+
+use std::ops::*;
+
+fn main() {
+    assert_eq!(i8::neg(-0x80), -0x80);
+
+    assert_eq!(u8::add(0xff, 1), 0_u8);
+    assert_eq!(u8::sub(0, 1), 0xff_u8);
+    assert_eq!(u8::mul(0xff, 2), 0xfe_u8);
+    assert_eq!(u8::shl(1, 9), 2_u8);
+    assert_eq!(u8::shr(2, 9), 1_u8);
+}
diff --git a/src/test/run-pass/simd-upgraded.rs b/src/test/run-pass/simd-upgraded.rs
new file mode 100644 (file)
index 0000000..821a505
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that removed LLVM SIMD intrinsics continue
+// to work via the "AutoUpgrade" mechanism.
+
+#![feature(cfg_target_feature, repr_simd)]
+#![feature(platform_intrinsics, stmt_expr_attributes)]
+
+#[repr(simd)]
+#[derive(PartialEq, Debug)]
+struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16);
+
+fn main() {
+    #[cfg(target_feature = "sse2")] unsafe {
+        extern "platform-intrinsic" {
+            fn x86_mm_min_epi16(x: i16x8, y: i16x8) -> i16x8;
+        }
+        assert_eq!(x86_mm_min_epi16(i16x8(0, 1, 2, 3, 4, 5, 6, 7),
+                                    i16x8(7, 6, 5, 4, 3, 2, 1, 0)),
+                                    i16x8(0, 1, 2, 3, 3, 2, 1, 0));
+    };
+}
diff --git a/src/test/run-pass/slice_binary_search.rs b/src/test/run-pass/slice_binary_search.rs
new file mode 100644 (file)
index 0000000..80b370d
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test binary_search_by_key lifetime. Issue #34683
+
+#[derive(Debug)]
+struct Assignment {
+    topic: String,
+    partition: i32,
+}
+
+fn main() {
+    let xs = vec![
+        Assignment { topic: "abc".into(), partition: 1 },
+        Assignment { topic: "def".into(), partition: 2 },
+        Assignment { topic: "ghi".into(), partition: 3 },
+    ];
+
+    let key: &str = "def";
+    let r = xs.binary_search_by_key(&key, |e| &e.topic);
+    assert_eq!(Ok(1), r.map(|i| i));
+}
diff --git a/src/test/run-pass/type-id-higher-rank-2.rs b/src/test/run-pass/type-id-higher-rank-2.rs
new file mode 100644 (file)
index 0000000..aead8bc
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that we can't ignore lifetimes by going through Any.
+
+use std::any::Any;
+
+struct Foo<'a>(&'a str);
+
+fn good(s: &String) -> Foo { Foo(s) }
+
+fn bad1(s: String) -> Option<&'static str> {
+    let a: Box<Any> = Box::new(good as fn(&String) -> Foo);
+    a.downcast_ref::<fn(&String) -> Foo<'static>>().map(|f| f(&s).0)
+}
+
+trait AsStr<'a, 'b> {
+    fn get(&'a self) -> &'b str;
+}
+
+impl<'a> AsStr<'a, 'a> for String {
+   fn get(&'a self) -> &'a str { self }
+}
+
+fn bad2(s: String) -> Option<&'static str> {
+    let a: Box<Any> = Box::new(Box::new(s) as Box<for<'a> AsStr<'a, 'a>>);
+    a.downcast_ref::<Box<for<'a> AsStr<'a, 'static>>>().map(|x| x.get())
+}
+
+fn main() {
+    assert_eq!(bad1(String::from("foo")), None);
+    assert_eq!(bad2(String::from("bar")), None);
+}
index c29fb5e86f51d54311b2db332b85c7a64910330d..827b05c0801e1eb39b5650defc365315f411b3d3 100644 (file)
@@ -16,6 +16,9 @@
 
 use std::any::{Any, TypeId};
 
+struct Struct<'a>(&'a ());
+trait Trait<'a> {}
+
 fn main() {
     // Bare fns
     {
@@ -34,6 +37,14 @@ fn main() {
         let e = TypeId::of::<for<'a> fn(fn(&'a isize) -> &'a isize)>();
         let f = TypeId::of::<fn(for<'a> fn(&'a isize) -> &'a isize)>();
         assert!(e != f);
+
+        // Make sure lifetime parameters of items are not ignored.
+        let g = TypeId::of::<for<'a> fn(&'a Trait<'a>) -> Struct<'a>>();
+        let h = TypeId::of::<for<'a> fn(&'a Trait<'a>) -> Struct<'static>>();
+        let i = TypeId::of::<for<'a, 'b> fn(&'a Trait<'b>) -> Struct<'b>>();
+        assert!(g != h);
+        assert!(g != i);
+        assert!(h != i);
     }
     // Boxed unboxed closures
     {
index 4bd82baafeb100c32897ccf9584969dc98902d2d..e99a5f69af40f23c984301370f54297b6034de1f 100644 (file)
 struct Test;
 
 pub fn main() {
-    unsafe {
-        assert_eq!(TypeId::of::<other1::A>(), other1::id_A());
-        assert_eq!(TypeId::of::<other1::B>(), other1::id_B());
-        assert_eq!(TypeId::of::<other1::C>(), other1::id_C());
-        assert_eq!(TypeId::of::<other1::D>(), other1::id_D());
-        assert_eq!(TypeId::of::<other1::E>(), other1::id_E());
-        assert_eq!(TypeId::of::<other1::F>(), other1::id_F());
-        assert_eq!(TypeId::of::<other1::G>(), other1::id_G());
-        assert_eq!(TypeId::of::<other1::H>(), other1::id_H());
+    assert_eq!(TypeId::of::<other1::A>(), other1::id_A());
+    assert_eq!(TypeId::of::<other1::B>(), other1::id_B());
+    assert_eq!(TypeId::of::<other1::C>(), other1::id_C());
+    assert_eq!(TypeId::of::<other1::D>(), other1::id_D());
+    assert_eq!(TypeId::of::<other1::E>(), other1::id_E());
+    assert_eq!(TypeId::of::<other1::F>(), other1::id_F());
+    assert_eq!(TypeId::of::<other1::G>(), other1::id_G());
+    assert_eq!(TypeId::of::<other1::H>(), other1::id_H());
+    assert_eq!(TypeId::of::<other1::I>(), other1::id_I());
 
-        assert_eq!(TypeId::of::<other2::A>(), other2::id_A());
-        assert_eq!(TypeId::of::<other2::B>(), other2::id_B());
-        assert_eq!(TypeId::of::<other2::C>(), other2::id_C());
-        assert_eq!(TypeId::of::<other2::D>(), other2::id_D());
-        assert_eq!(TypeId::of::<other2::E>(), other2::id_E());
-        assert_eq!(TypeId::of::<other2::F>(), other2::id_F());
-        assert_eq!(TypeId::of::<other2::G>(), other2::id_G());
-        assert_eq!(TypeId::of::<other2::H>(), other2::id_H());
+    assert_eq!(TypeId::of::<other2::A>(), other2::id_A());
+    assert_eq!(TypeId::of::<other2::B>(), other2::id_B());
+    assert_eq!(TypeId::of::<other2::C>(), other2::id_C());
+    assert_eq!(TypeId::of::<other2::D>(), other2::id_D());
+    assert_eq!(TypeId::of::<other2::E>(), other2::id_E());
+    assert_eq!(TypeId::of::<other2::F>(), other2::id_F());
+    assert_eq!(TypeId::of::<other2::G>(), other2::id_G());
+    assert_eq!(TypeId::of::<other2::H>(), other2::id_H());
+    assert_eq!(TypeId::of::<other1::I>(), other2::id_I());
 
-        assert_eq!(other1::id_F(), other2::id_F());
-        assert_eq!(other1::id_G(), other2::id_G());
-        assert_eq!(other1::id_H(), other2::id_H());
+    assert_eq!(other1::id_F(), other2::id_F());
+    assert_eq!(other1::id_G(), other2::id_G());
+    assert_eq!(other1::id_H(), other2::id_H());
+    assert_eq!(other1::id_I(), other2::id_I());
 
-        assert_eq!(TypeId::of::<isize>(), other2::foo::<isize>());
-        assert_eq!(TypeId::of::<isize>(), other1::foo::<isize>());
-        assert_eq!(other2::foo::<isize>(), other1::foo::<isize>());
-        assert_eq!(TypeId::of::<A>(), other2::foo::<A>());
-        assert_eq!(TypeId::of::<A>(), other1::foo::<A>());
-        assert_eq!(other2::foo::<A>(), other1::foo::<A>());
-    }
+    assert_eq!(TypeId::of::<isize>(), other2::foo::<isize>());
+    assert_eq!(TypeId::of::<isize>(), other1::foo::<isize>());
+    assert_eq!(other2::foo::<isize>(), other1::foo::<isize>());
+    assert_eq!(TypeId::of::<A>(), other2::foo::<A>());
+    assert_eq!(TypeId::of::<A>(), other1::foo::<A>());
+    assert_eq!(other2::foo::<A>(), other1::foo::<A>());
 
     // sanity test of TypeId
     let (a, b, c) = (TypeId::of::<usize>(), TypeId::of::<&'static str>(),
index 6c388cd69395b272b7dc7d224e8a1b9ac708d09d..69560174346160fb1bb1146b655c470b25571459 100644 (file)
@@ -2,12 +2,9 @@ error[E0404]: `Bar` is not a trait
   --> $DIR/two_files.rs:16:6
    |
 16 | impl Bar for Baz { }
-   |      ^^^ `Bar` is not a trait
-   | 
-  ::: $DIR/two_files_data.rs
+   |      ^^^ not a trait
    |
-15 | type Bar = Foo;
-   | --------------- type aliases cannot be used for traits
+   = note: type aliases cannot be used for traits
 
 error: cannot continue compilation due to previous error
 
index 8b7164819a7907390d3105335ae38039d47b9d65..72df09b7669f686ed4303f3fab6f0d93bc564fa9 100644 (file)
@@ -24,7 +24,7 @@ struct Test {
 const TEST_REPOS: &'static [Test] = &[Test {
                                           name: "cargo",
                                           repo: "https://github.com/rust-lang/cargo",
-                                          sha: "7d79da08238e3d47e0bc4406155bdcc45ccb8c82",
+                                          sha: "fd90fd642d404d8c66505ca8db742c664ea352f2",
                                           lock: None,
                                       },
                                       Test {
index f2acfa517ced5b3e36aa75afa5537ac5cfbcbf1f..6647a1a0a933d41046dc22ad79e0709a52393967 100644 (file)
@@ -1340,6 +1340,8 @@ fn make_compile_args(&self,
             MirOpt => {
                 args.extend(["-Z",
                              "dump-mir=all",
+                             "-Z",
+                             "mir-opt-level=3",
                              "-Z"]
                             .iter()
                             .map(|s| s.to_string()));