]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #30468 - Eljay:fix-doc-link, r=alexcrichton
authorbors <bors@rust-lang.org>
Sun, 20 Dec 2015 16:34:09 +0000 (16:34 +0000)
committerbors <bors@rust-lang.org>
Sun, 20 Dec 2015 16:34:09 +0000 (16:34 +0000)
152 files changed:
configure
mk/cfg/le32-unknown-nacl.mk [new file with mode: 0644]
mk/main.mk
src/doc/reference.md
src/libcore/num/dec2flt/mod.rs
src/liblibc
src/librand/isaac.rs
src/librustc/middle/cfg/construct.rs
src/librustc/middle/check_const.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/infer/error_reporting.rs
src/librustc/middle/infer/mod.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/traits/error_reporting.rs
src/librustc/middle/traits/fulfill.rs
src/librustc/middle/traits/mod.rs
src/librustc/middle/traits/select.rs
src/librustc/middle/ty/mod.rs
src/librustc/middle/ty/outlives.rs
src/librustc/middle/ty/wf.rs
src/librustc/session/mod.rs
src/librustc_back/rpath.rs
src/librustc_back/svh.rs
src/librustc_front/fold.rs
src/librustc_front/hir.rs
src/librustc_front/intravisit.rs
src/librustc_front/lowering.rs
src/librustc_front/print/pprust.rs
src/librustc_lint/unused.rs
src/librustc_llvm/lib.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_trans/back/link.rs
src/librustc_trans/trans/consts.rs
src/librustc_trans/trans/debuginfo/create_scope_map.rs
src/librustc_trans/trans/expr.rs
src/librustc_trans/trans/mir/block.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/wf.rs [deleted file]
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/coherence/overlap.rs
src/librustc_typeck/diagnostics.rs
src/librustc_typeck/lib.rs
src/libstd/ffi/c_str.rs
src/libstd/io/buffered.rs
src/libstd/io/mod.rs
src/libstd/lib.rs
src/libstd/memchr.rs [new file with mode: 0644]
src/libstd/process.rs
src/libstd/rand/mod.rs
src/libstd/rand/os.rs
src/libstd/sys/unix/fs.rs
src/libstd/sys/unix/os.rs
src/libsyntax/ast.rs
src/libsyntax/feature_gate.rs
src/libsyntax/fold.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/util/parser.rs
src/libsyntax/visit.rs
src/libsyntax_ext/asm.rs
src/libtest/lib.rs
src/rt/rust_builtin.c
src/test/auxiliary/associated-types-cc-lib.rs
src/test/auxiliary/static-methods-crate.rs
src/test/compile-fail/associated-types-no-suitable-supertrait.rs
src/test/compile-fail/builtin-superkinds-self-type.rs
src/test/compile-fail/coerce-expect-unsized-ascribed.rs [new file with mode: 0644]
src/test/compile-fail/coherence-impl-trait-for-trait-object-safe.rs
src/test/compile-fail/cross-fn-cache-hole.rs
src/test/compile-fail/issue-13853-2.rs
src/test/compile-fail/issue-13853.rs
src/test/compile-fail/issue-14853.rs
src/test/compile-fail/issue-18959.rs
src/test/compile-fail/issue-19380.rs
src/test/compile-fail/issue-20005.rs
src/test/compile-fail/issue-20831-debruijn.rs
src/test/compile-fail/issue-21974.rs
src/test/compile-fail/issue-23041.rs
src/test/compile-fail/issue-23305.rs
src/test/compile-fail/issue-3907-2.rs
src/test/compile-fail/object-safety-generics.rs
src/test/compile-fail/object-safety-mentions-Self.rs
src/test/compile-fail/object-safety-no-static.rs
src/test/compile-fail/object-safety-sized-2.rs
src/test/compile-fail/object-safety-sized.rs
src/test/compile-fail/regions-close-object-into-object-5.rs
src/test/compile-fail/regions-free-region-ordering-callee-4.rs [new file with mode: 0644]
src/test/compile-fail/regions-free-region-ordering-callee.rs
src/test/compile-fail/regions-implied-bounds-projection-gap-hr-1.rs
src/test/compile-fail/regions-wf-trait-object.rs
src/test/compile-fail/rfc1214-warn-and-error.rs [deleted file]
src/test/compile-fail/trait-bounds-impl-comparison-2.rs
src/test/compile-fail/trait-test-2.rs
src/test/compile-fail/type-ascription-feature-gate.rs [new file with mode: 0644]
src/test/compile-fail/type-ascription-precedence.rs [new file with mode: 0644]
src/test/compile-fail/type-ascription-soundness.rs [new file with mode: 0644]
src/test/compile-fail/typeck-default-trait-impl-trait-where-clause-2.rs [new file with mode: 0644]
src/test/compile-fail/typeck-default-trait-impl-trait-where-clause.rs
src/test/compile-fail/variance-invariant-self-trait-match.rs
src/test/compile-fail/wf-array-elem-sized.rs
src/test/compile-fail/wf-enum-bound.rs
src/test/compile-fail/wf-fn-where-clause.rs
src/test/compile-fail/wf-impl-associated-type-region.rs
src/test/compile-fail/wf-impl-associated-type-trait.rs
src/test/compile-fail/wf-in-fn-type-static.rs
src/test/compile-fail/wf-in-fn-where-clause.rs
src/test/compile-fail/wf-in-obj-type-static.rs
src/test/compile-fail/wf-inherent-impl-method-where-clause.rs
src/test/compile-fail/wf-inherent-impl-where-clause.rs
src/test/compile-fail/wf-outlives-ty-in-fn-or-trait.rs
src/test/compile-fail/wf-struct-bound.rs
src/test/compile-fail/wf-trait-associated-type-bound.rs
src/test/compile-fail/wf-trait-associated-type-region.rs
src/test/compile-fail/wf-trait-associated-type-trait.rs
src/test/compile-fail/wf-trait-bound.rs
src/test/compile-fail/wf-trait-default-fn-arg.rs
src/test/compile-fail/wf-trait-default-fn-ret.rs
src/test/compile-fail/wf-trait-default-fn-where-clause.rs
src/test/compile-fail/wf-trait-fn-arg.rs
src/test/compile-fail/wf-trait-fn-ret.rs
src/test/compile-fail/wf-trait-fn-where-clause.rs
src/test/compile-fail/wf-trait-superbound.rs
src/test/parse-fail/struct-literal-in-for.rs
src/test/parse-fail/struct-literal-in-if.rs
src/test/parse-fail/struct-literal-in-while.rs
src/test/run-pass/cycle-generic-bound.rs
src/test/run-pass/cycle-trait-type-trait.rs
src/test/run-pass/issue-25810.rs
src/test/run-pass/issue-26873-multifile.rs [new file with mode: 0644]
src/test/run-pass/issue-26873-onefile.rs [new file with mode: 0644]
src/test/run-pass/issue-6898.rs
src/test/run-pass/issue_26873_multifile/A/B.rs [new file with mode: 0644]
src/test/run-pass/issue_26873_multifile/A/C.rs [new file with mode: 0644]
src/test/run-pass/issue_26873_multifile/A/mod.rs [new file with mode: 0644]
src/test/run-pass/issue_26873_multifile/mod.rs [new file with mode: 0644]
src/test/run-pass/mir_trans_calls.rs [new file with mode: 0644]
src/test/run-pass/regions-issue-22246.rs
src/test/run-pass/regions-no-variance-from-fn-generics.rs
src/test/run-pass/trait-inheritance-num0.rs
src/test/run-pass/trait-inheritance-num1.rs
src/test/run-pass/trait-inheritance-num3.rs
src/test/run-pass/trait-inheritance-num5.rs
src/test/run-pass/trait-inheritance-self-in-supertype.rs
src/test/run-pass/trait-inheritance-self.rs
src/test/run-pass/trait-inheritance-subst.rs
src/test/run-pass/trait-inheritance-subst2.rs
src/test/run-pass/type-ascription.rs [new file with mode: 0644]
src/test/run-pass/unsized2.rs

index 4c5fa4aaa604d735f3dee528256f6955a23687bb..6e2d3060bc3c0d66d091cd3fc473322346e93a89 100755 (executable)
--- a/configure
+++ b/configure
@@ -616,6 +616,7 @@ valopt android-cross-path "/opt/ndk_standalone" "Android NDK standalone path (de
 valopt i686-linux-android-ndk "" "i686-linux-android NDK standalone path"
 valopt arm-linux-androideabi-ndk "" "arm-linux-androideabi NDK standalone path"
 valopt aarch64-linux-android-ndk "" "aarch64-linux-android NDK standalone path"
+valopt nacl-cross-path  "" "NaCl SDK path (Pepper Canary is recommended). Must be absolute!"
 valopt release-channel "dev" "the name of the release channel to build"
 valopt musl-root "/usr/local" "MUSL root installation directory"
 
@@ -1147,7 +1148,12 @@ do
                 fi
             done
             ;;
-
+        *-unknown-nacl)
+           if [ -z "$CFG_NACL_CROSS_PATH" ]
+           then
+               err "I need the NaCl SDK path! (use --nacl-cross-path)"
+           fi
+           ;;
         arm-apple-darwin)
             if [ $CFG_OSTYPE != apple-darwin ]
             then
@@ -1749,6 +1755,7 @@ putvar CFG_DISABLE_MANAGE_SUBMODULES
 putvar CFG_AARCH64_LINUX_ANDROID_NDK
 putvar CFG_ARM_LINUX_ANDROIDEABI_NDK
 putvar CFG_I686_LINUX_ANDROID_NDK
+putvar CFG_NACL_CROSS_PATH
 putvar CFG_MANDIR
 putvar CFG_USING_LIBCPP
 
diff --git a/mk/cfg/le32-unknown-nacl.mk b/mk/cfg/le32-unknown-nacl.mk
new file mode 100644 (file)
index 0000000..a733672
--- /dev/null
@@ -0,0 +1,40 @@
+# le32-unknown-nacl (portable, PNaCl)
+ifneq ($(CFG_NACL_CROSS_PATH),)
+
+CC_le32-unknown-nacl=$(shell $(CFG_PYTHON) $(CFG_NACL_CROSS_PATH)/tools/nacl_config.py -t pnacl --tool cc)
+CXX_le32-unknown-nacl=$(shell $(CFG_PYTHON) $(CFG_NACL_CROSS_PATH)/tools/nacl_config.py -t pnacl --tool c++)
+CPP_le32-unknown-nacl=$(CXX_le32-unknown-nacl) -E
+AR_le32-unknown-nacl=$(shell $(CFG_PYTHON) $(CFG_NACL_CROSS_PATH)/tools/nacl_config.py -t pnacl --tool ar)
+
+CFG_PNACL_TOOLCHAIN := $(abspath $(dir $(AR_le32-unknown-nacl)/../))
+
+# Note: pso's aren't supported by PNaCl.
+CFG_LIB_NAME_le32-unknown-nacl=lib$(1).pso
+CFG_STATIC_LIB_NAME_le32-unknown-nacl=lib$(1).a
+CFG_LIB_GLOB_le32-unknown-nacl=lib$(1)-*.pso
+CFG_LIB_DSYM_GLOB_le32-unknown-nacl=lib$(1)-*.dylib.dSYM
+CFG_GCCISH_CFLAGS_le32-unknown-nacl := -Wall -Wno-unused-variable -Wno-unused-value $(shell $(CFG_PYTHON) $(CFG_NACL_CROSS_PATH)/tools/nacl_config.py -t pnacl --cflags) -D_YUGA_LITTLE_ENDIAN=1 -D_YUGA_BIG_ENDIAN=0
+CFG_GCCISH_CXXFLAGS_le32-unknown-nacl := -stdlib=libc++ $(CFG_GCCISH_CFLAGS_le32-unknown-nacl)
+CFG_GCCISH_LINK_FLAGS_le32-unknown-nacl := -static -pthread -lm
+CFG_GCCISH_DEF_FLAG_le32-unknown-nacl := -Wl,--export-dynamic,--dynamic-list=
+CFG_GCCISH_PRE_LIB_FLAGS_le32-unknown-nacl := -Wl,-no-whole-archive
+CFG_GCCISH_POST_LIB_FLAGS_le32-unknown-nacl :=
+CFG_DEF_SUFFIX_le32-unknown-nacl := .le32.nacl.def
+CFG_INSTALL_NAME_le32-unknown-nacl =
+CFG_EXE_SUFFIX_le32-unknown-nacl = .pexe
+CFG_WINDOWSY_le32-unknown-nacl :=
+CFG_UNIXY_le32-unknown-nacl := 1
+CFG_NACLY_le32-unknown-nacl := 1
+CFG_PATH_MUNGE_le32-unknown-nacl := true
+CFG_LDPATH_le32-unknown-nacl :=
+CFG_RUN_le32-unknown-nacl=$(2)
+CFG_RUN_TARG_le32-unknown-nacl=$(call CFG_RUN_le32-unknown-nacl,,$(2))
+RUSTC_FLAGS_le32-unknown-nacl:=
+RUSTC_CROSS_FLAGS_le32-unknown-nacl=-L $(CFG_NACL_CROSS_PATH)/lib/pnacl/Release -L $(CFG_PNACL_TOOLCHAIN)/lib/clang/3.7.0/lib/le32-nacl -L $(CFG_PNACL_TOOLCHAIN)/le32-nacl/usr/lib -L $(CFG_PNACL_TOOLCHAIN)/le32-nacl/lib
+CFG_GNU_TRIPLE_le32-unknown-nacl := le32-unknown-nacl
+
+# strdup isn't defined unless -std=gnu++11 is used :/
+LLVM_FILTER_CXXFLAGS_le32-unknown-nacl := -std=c++11
+LLVM_EXTRA_CXXFLAGS_le32-unknown-nacl := -std=gnu++11
+
+endif
index f2ff4f1c3a2bfe2f81ba4bf0a1458ab2dad5117b..110bf0408d63c1966df6d44edbaac2599b8733ca 100644 (file)
@@ -276,7 +276,7 @@ endif
 # LLVM macros
 ######################################################################
 
-LLVM_OPTIONAL_COMPONENTS=x86 arm aarch64 mips powerpc
+LLVM_OPTIONAL_COMPONENTS=x86 arm aarch64 mips powerpc pnacl
 LLVM_REQUIRED_COMPONENTS=ipo bitreader bitwriter linker asmparser mcjit \
                 interpreter instrumentation
 
index a722c0e38f4c09b5ad53063a0d5a5dbee3b9ef27..e7cc1436824e42dcd500d7bfff4685ca065e06ee 100644 (file)
@@ -2388,6 +2388,8 @@ The currently implemented features of the reference compiler are:
 
 * - `deprecated` - Allows using the `#[deprecated]` attribute.
 
+* - `type_ascription` - Allows type ascription expressions `expr: Type`.
+
 If a feature is promoted to a language feature, then all existing programs will
 start to receive compilation warnings about `#![feature]` directives which enabled
 the new feature (because the directive is no longer necessary). However, if a
index 9c0ec0f22c50fc387843cc2feb3097622e558cc0..6acc621a6137630e4b11faa6cc74e538894b6822 100644 (file)
@@ -96,8 +96,7 @@
 use fmt;
 use str::FromStr;
 
-use self::parse::{parse_decimal, Decimal, Sign};
-use self::parse::ParseResult::{Valid, Invalid, ShortcutToInf, ShortcutToZero};
+use self::parse::{parse_decimal, Decimal, Sign, ParseResult};
 use self::num::digits_to_big;
 use self::rawfp::RawFloat;
 
@@ -208,10 +207,10 @@ fn dec2flt<T: RawFloat>(s: &str) -> Result<T, ParseFloatError> {
     }
     let (sign, s) = extract_sign(s);
     let flt = match parse_decimal(s) {
-        Valid(decimal) => try!(convert(decimal)),
-        ShortcutToInf => T::infinity(),
-        ShortcutToZero => T::zero(),
-        Invalid => match s {
+        ParseResult::Valid(decimal) => try!(convert(decimal)),
+        ParseResult::ShortcutToInf => T::infinity(),
+        ParseResult::ShortcutToZero => T::zero(),
+        ParseResult::Invalid => match s {
             "inf" => T::infinity(),
             "NaN" => T::nan(),
             _ => { return Err(pfe_invalid()); }
index 867c6ff0b824d6d295951ed34bb252d5e0b2467a..4b9b07c71997da23d5d1e3035cd16a5855b94ecc 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 867c6ff0b824d6d295951ed34bb252d5e0b2467a
+Subproject commit 4b9b07c71997da23d5d1e3035cd16a5855b94ecc
index dd99bc93ef379bf532beb12d14482e7bb33e486c..28eff87bde3b762246e11abec3c6039d93c51b21 100644 (file)
@@ -77,14 +77,37 @@ fn init(&mut self, use_rsl: bool) {
 
         macro_rules! mix {
             () => {{
-                a=a^(b<<11); d=d+a; b=b+c;
-                b=b^(c>>2);  e=e+b; c=c+d;
-                c=c^(d<<8);  f=f+c; d=d+e;
-                d=d^(e>>16); g=g+d; e=e+f;
-                e=e^(f<<10); h=h+e; f=f+g;
-                f=f^(g>>4);  a=a+f; g=g+h;
-                g=g^(h<<8);  b=b+g; h=h+a;
-                h=h^(a>>9);  c=c+h; a=a+b;
+                a = a ^ (b << 11);
+                d = d + a;
+                b = b + c;
+
+                b = b ^ (c >> 2);
+                e = e + b;
+                c = c + d;
+
+                c = c ^ (d << 8);
+                f = f + c;
+                d = d + e;
+
+                d = d ^ (e >> 16);
+                g = g + d;
+                e = e + f;
+
+                e = e ^ (f << 10);
+                h = h + e;
+                f = f + g;
+
+                f = f ^ (g >> 4);
+                a = a + f;
+                g = g + h;
+
+                g = g ^ (h << 8);
+                b = b + g;
+                h = h + a;
+
+                h = h ^ (a >> 9);
+                c = c + h;
+                a = a + b;
             }}
         }
 
@@ -337,14 +360,37 @@ macro_rules! init {
 
         macro_rules! mix {
             () => {{
-                a=a-e; f=f^(h>>9);  h=h+a;
-                b=b-f; g=g^(a<<9);  a=a+b;
-                c=c-g; h=h^(b>>23); b=b+c;
-                d=d-h; a=a^(c<<15); c=c+d;
-                e=e-a; b=b^(d>>14); d=d+e;
-                f=f-b; c=c^(e<<20); e=e+f;
-                g=g-c; d=d^(f>>17); f=f+g;
-                h=h-d; e=e^(g<<14); g=g+h;
+                a = a - e;
+                f = f ^ (h >> 9);
+                h = h + a;
+
+                b = b - f;
+                g = g ^ (a << 9);
+                a = a + b;
+
+                c = c - g;
+                h = h ^ (b >> 23);
+                b = b + c;
+
+                d = d - h;
+                a = a ^ (c << 15);
+                c = c + d;
+
+                e = e - a;
+                b = b ^ (d >> 14);
+                d = d + e;
+
+                f = f - b;
+                c = c ^ (e << 20);
+                e = e + f;
+
+                g = g - c;
+                d = d ^ (f >> 17);
+                f = f + g;
+
+                h = h - d;
+                e = e ^ (g << 14);
+                g = g + h;
             }}
         }
 
index 8baae99c2f24b57e492bbf6dca2f583a1a7af2bf..abe85125215708f38abd8038f0295e6efb8df76b 100644 (file)
@@ -352,6 +352,7 @@ fn expr(&mut self, expr: &hir::Expr, pred: CFGIndex) -> CFGIndex {
             hir::ExprBox(ref e) |
             hir::ExprAddrOf(_, ref e) |
             hir::ExprCast(ref e, _) |
+            hir::ExprType(ref e, _) |
             hir::ExprUnary(_, ref e) |
             hir::ExprField(ref e, _) |
             hir::ExprTupField(ref e, _) => {
index 69d8dfc361328e10440e8c8e93212e2cedec3e7f..d6f05ffd8a513013a6e36ebeb886fcb97492154f 100644 (file)
@@ -784,6 +784,7 @@ struct and enum constructors",
         hir::ExprField(..) |
         hir::ExprTupField(..) |
         hir::ExprVec(_) |
+        hir::ExprType(..) |
         hir::ExprTup(..) => {}
 
         // Conditional control flow (possible to implement).
index 54061a14d1419644ff1880c9849dbdf5a433f63b..d5cfff4aff8a466f3a0090eb4e7063303630b7e7 100644 (file)
@@ -1126,6 +1126,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
             None => unreachable!(),
         }
       }
+      hir::ExprType(ref e, _) => try!(eval_const_expr_partial(tcx, &**e, ty_hint, fn_args)),
       hir::ExprTup(_) => Tuple(e.id),
       hir::ExprStruct(..) => Struct(e.id),
       hir::ExprIndex(ref arr, ref idx) => {
index 73776304bc846d65cec3a38d1dc0a8a9326e25c7..ff3e99d487c9e41b4e75e050ddd425eb23fb32c6 100644 (file)
@@ -373,6 +373,10 @@ pub fn walk_expr(&mut self, expr: &hir::Expr) {
         match expr.node {
             hir::ExprPath(..) => { }
 
+            hir::ExprType(ref subexpr, _) => {
+                self.walk_expr(&**subexpr)
+            }
+
             hir::ExprUnary(hir::UnDeref, ref base) => {      // *base
                 if !self.walk_overloaded_operator(expr, &**base, Vec::new(), PassArgs::ByRef) {
                     self.select_from_expr(&**base);
index 2abf499185690f7c8bd9ef3f251946637cb095f4..7bb66d6317abdc52b515d928827db543a4920480 100644 (file)
@@ -577,11 +577,6 @@ fn report_generic_bound_failure(&self,
         // where the error was detected. But that span is not readily
         // accessible.
 
-        let is_warning = match origin {
-            infer::RFC1214Subregion(_) => true,
-            _ => false,
-        };
-
         let labeled_user_string = match bound_kind {
             GenericKind::Param(ref p) =>
                 format!("the parameter type `{}`", p),
@@ -592,8 +587,8 @@ fn report_generic_bound_failure(&self,
         match sub {
             ty::ReFree(ty::FreeRegion {bound_region: ty::BrNamed(..), ..}) => {
                 // Does the required lifetime have a nice name we can print?
-                span_err_or_warn!(
-                    is_warning, self.tcx.sess, origin.span(), E0309,
+                span_err!(
+                    self.tcx.sess, origin.span(), E0309,
                     "{} may not live long enough", labeled_user_string);
                 self.tcx.sess.fileline_help(
                     origin.span(),
@@ -605,8 +600,8 @@ fn report_generic_bound_failure(&self,
 
             ty::ReStatic => {
                 // Does the required lifetime have a nice name we can print?
-                span_err_or_warn!(
-                    is_warning, self.tcx.sess, origin.span(), E0310,
+                span_err!(
+                    self.tcx.sess, origin.span(), E0310,
                     "{} may not live long enough", labeled_user_string);
                 self.tcx.sess.fileline_help(
                     origin.span(),
@@ -617,8 +612,8 @@ fn report_generic_bound_failure(&self,
 
             _ => {
                 // If not, be less specific.
-                span_err_or_warn!(
-                    is_warning, self.tcx.sess, origin.span(), E0311,
+                span_err!(
+                    self.tcx.sess, origin.span(), E0311,
                     "{} may not live long enough",
                     labeled_user_string);
                 self.tcx.sess.fileline_help(
@@ -633,10 +628,6 @@ fn report_generic_bound_failure(&self,
             }
         }
 
-        if is_warning {
-            self.tcx.sess.note_rfc_1214(origin.span());
-        }
-
         self.note_region_origin(&origin);
     }
 
@@ -645,13 +636,6 @@ fn report_concrete_failure(&self,
                                sub: Region,
                                sup: Region) {
         match origin {
-            infer::RFC1214Subregion(ref suborigin) => {
-                // Ideally, this would be a warning, but it doesn't
-                // seem to come up in practice, since the changes from
-                // RFC1214 mostly trigger errors in type definitions
-                // that don't wind up coming down this path.
-                self.report_concrete_failure((**suborigin).clone(), sub, sup);
-            }
             infer::Subtype(trace) => {
                 let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
                 self.report_and_explain_type_error(trace, &terr);
@@ -1598,9 +1582,6 @@ fn report_inference_failure(&self,
 
     fn note_region_origin(&self, origin: &SubregionOrigin<'tcx>) {
         match *origin {
-            infer::RFC1214Subregion(ref suborigin) => {
-                self.note_region_origin(suborigin);
-            }
             infer::Subtype(ref trace) => {
                 let desc = match trace.origin {
                     TypeOrigin::Misc(_) => {
index 119651f12e912f85fbb04644f55ac08ce197ae66..d0ffed56635f7e3e183bd4de6a6359dc6bef0ca4 100644 (file)
@@ -37,7 +37,6 @@
 use rustc_data_structures::unify::{self, UnificationTable};
 use std::cell::{RefCell, Ref};
 use std::fmt;
-use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap;
 use syntax::codemap::{Span, DUMMY_SP};
@@ -198,11 +197,6 @@ pub struct TypeTrace<'tcx> {
 /// See `error_reporting.rs` for more details
 #[derive(Clone, Debug)]
 pub enum SubregionOrigin<'tcx> {
-    // Marker to indicate a constraint that only arises due to new
-    // provisions from RFC 1214. This will result in a warning, not an
-    // error.
-    RFC1214Subregion(Rc<SubregionOrigin<'tcx>>),
-
     // Arose from a subtyping relation
     Subtype(TypeTrace<'tcx>),
 
@@ -1568,7 +1562,6 @@ pub fn span(&self) -> Span {
 impl<'tcx> SubregionOrigin<'tcx> {
     pub fn span(&self) -> Span {
         match *self {
-            RFC1214Subregion(ref a) => a.span(),
             Subtype(ref a) => a.span(),
             InfStackClosure(a) => a,
             InvokeClosure(a) => a,
index 4a75309f1a65c4757fd4b76ba953b7719930b2a7..540af4ae001656a807208f63d90a5ac54a0c5657 100644 (file)
@@ -496,7 +496,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
       hir::ExprBlock(..) | hir::ExprAssign(..) | hir::ExprAssignOp(..) |
       hir::ExprStruct(..) | hir::ExprRepeat(..) |
       hir::ExprInlineAsm(..) | hir::ExprBox(..) |
-      hir::ExprRange(..) => {
+      hir::ExprRange(..) | hir::ExprType(..) => {
           intravisit::walk_expr(ir, expr);
       }
     }
@@ -1160,6 +1160,7 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
           hir::ExprBox(ref e) |
           hir::ExprAddrOf(_, ref e) |
           hir::ExprCast(ref e, _) |
+          hir::ExprType(ref e, _) |
           hir::ExprUnary(_, ref e) => {
             self.propagate_through_expr(&**e, succ)
           }
@@ -1443,7 +1444,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
       hir::ExprBlock(..) | hir::ExprAddrOf(..) |
       hir::ExprStruct(..) | hir::ExprRepeat(..) |
       hir::ExprClosure(..) | hir::ExprPath(..) | hir::ExprBox(..) |
-      hir::ExprRange(..) => {
+      hir::ExprRange(..) | hir::ExprType(..) => {
         intravisit::walk_expr(this, expr);
       }
     }
index 560d7eeed9e5c4ff7512a56ba4046223529bbc6e..1eb5efa0bda446eb88fe613d786608c88fb4359f 100644 (file)
@@ -518,6 +518,10 @@ pub fn cat_expr_unadjusted(&self, expr: &hir::Expr) -> McResult<cmt<'tcx>> {
             self.cat_def(expr.id, expr.span, expr_ty, def)
           }
 
+          hir::ExprType(ref e, _) => {
+            self.cat_expr(&**e)
+          }
+
           hir::ExprAddrOf(..) | hir::ExprCall(..) |
           hir::ExprAssign(..) | hir::ExprAssignOp(..) |
           hir::ExprClosure(..) | hir::ExprRet(..) |
index 0931c138e46f4107058e6df7ab788fac5045150f..9cf8043be3ba1bf6c34bd7bf6dc89e7658bad50b 100644 (file)
@@ -36,7 +36,6 @@
 
 #[derive(Debug, PartialEq, Eq, Hash)]
 pub struct TraitErrorKey<'tcx> {
-    is_warning: bool,
     span: Span,
     predicate: ty::Predicate<'tcx>
 }
@@ -47,7 +46,6 @@ fn from_error<'a>(infcx: &InferCtxt<'a, 'tcx>,
         let predicate =
             infcx.resolve_type_vars_if_possible(&e.obligation.predicate);
         TraitErrorKey {
-            is_warning: is_warning(&e.obligation),
             span: e.obligation.cause.span,
             predicate: infcx.tcx.erase_regions(&predicate)
         }
@@ -83,10 +81,6 @@ fn report_fulfillment_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
     }
 }
 
-fn is_warning<T>(obligation: &Obligation<T>) -> bool {
-    obligation.cause.code.is_rfc1214()
-}
-
 pub fn report_projection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                                          obligation: &PredicateObligation<'tcx>,
                                          error: &MismatchedProjectionTypes<'tcx>)
@@ -100,8 +94,8 @@ pub fn report_projection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
     // then $X will be unified with TyError, but the error still needs to be
     // reported.
     if !infcx.tcx.sess.has_errors() || !predicate.references_error() {
-        span_err_or_warn!(
-            is_warning(obligation), infcx.tcx.sess, obligation.cause.span, E0271,
+        span_err!(
+            infcx.tcx.sess, obligation.cause.span, E0271,
             "type mismatch resolving `{}`: {}",
             predicate,
             error.err);
@@ -208,12 +202,11 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                                         obligation: &PredicateObligation<'tcx>,
                                         error: &SelectionError<'tcx>)
 {
-    let is_warning = is_warning(obligation);
     match *error {
         SelectionError::Unimplemented => {
             if let ObligationCauseCode::CompareImplMethodObligation = obligation.cause.code {
-                span_err_or_warn!(
-                    is_warning, infcx.tcx.sess, obligation.cause.span, E0276,
+                span_err!(
+                    infcx.tcx.sess, obligation.cause.span, E0276,
                     "the requirement `{}` appears on the impl \
                      method but not on the corresponding trait method",
                     obligation.predicate);
@@ -225,8 +218,8 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
 
                         if !infcx.tcx.sess.has_errors() || !trait_predicate.references_error() {
                             let trait_ref = trait_predicate.to_poly_trait_ref();
-                            span_err_or_warn!(
-                                is_warning, infcx.tcx.sess, obligation.cause.span, E0277,
+                            span_err!(
+                                infcx.tcx.sess, obligation.cause.span, E0277,
                                 "the trait `{}` is not implemented for the type `{}`",
                                 trait_ref, trait_ref.self_ty());
 
@@ -245,8 +238,8 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                         let predicate = infcx.resolve_type_vars_if_possible(predicate);
                         let err = infcx.equality_predicate(obligation.cause.span,
                                                            &predicate).err().unwrap();
-                        span_err_or_warn!(
-                            is_warning, infcx.tcx.sess, obligation.cause.span, E0278,
+                        span_err!(
+                            infcx.tcx.sess, obligation.cause.span, E0278,
                             "the requirement `{}` is not satisfied (`{}`)",
                             predicate,
                             err);
@@ -257,8 +250,8 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                         let predicate = infcx.resolve_type_vars_if_possible(predicate);
                         let err = infcx.region_outlives_predicate(obligation.cause.span,
                                                                   &predicate).err().unwrap();
-                        span_err_or_warn!(
-                            is_warning, infcx.tcx.sess, obligation.cause.span, E0279,
+                        span_err!(
+                            infcx.tcx.sess, obligation.cause.span, E0279,
                             "the requirement `{}` is not satisfied (`{}`)",
                             predicate,
                             err);
@@ -268,8 +261,8 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                     ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => {
                         let predicate =
                             infcx.resolve_type_vars_if_possible(&obligation.predicate);
-                        span_err_or_warn!(
-                            is_warning, infcx.tcx.sess, obligation.cause.span, E0280,
+                        span_err!(
+                            infcx.tcx.sess, obligation.cause.span, E0280,
                             "the requirement `{}` is not satisfied",
                             predicate);
                         note_obligation_cause(infcx, obligation);
@@ -281,8 +274,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                         report_object_safety_error(infcx.tcx,
                                                    obligation.cause.span,
                                                    trait_def_id,
-                                                   violations,
-                                                   is_warning);
+                                                   violations);
                         note_obligation_cause(infcx, obligation);
                     }
 
@@ -304,8 +296,8 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
             let expected_trait_ref = infcx.resolve_type_vars_if_possible(&*expected_trait_ref);
             let actual_trait_ref = infcx.resolve_type_vars_if_possible(&*actual_trait_ref);
             if !actual_trait_ref.self_ty().references_error() {
-                span_err_or_warn!(
-                    is_warning, infcx.tcx.sess, obligation.cause.span, E0281,
+                span_err!(
+                    infcx.tcx.sess, obligation.cause.span, E0281,
                     "type mismatch: the type `{}` implements the trait `{}`, \
                      but the trait `{}` is required ({})",
                     expected_trait_ref.self_ty(),
@@ -318,8 +310,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
 
         TraitNotObjectSafe(did) => {
             let violations = object_safety_violations(infcx.tcx, did);
-            report_object_safety_error(infcx.tcx, obligation.cause.span, did,
-                                       violations, is_warning);
+            report_object_safety_error(infcx.tcx, obligation.cause.span, did, violations);
             note_obligation_cause(infcx, obligation);
         }
     }
@@ -328,11 +319,10 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
 pub fn report_object_safety_error<'tcx>(tcx: &ty::ctxt<'tcx>,
                                         span: Span,
                                         trait_def_id: DefId,
-                                        violations: Vec<ObjectSafetyViolation>,
-                                        is_warning: bool)
+                                        violations: Vec<ObjectSafetyViolation>)
 {
-    span_err_or_warn!(
-        is_warning, tcx.sess, span, E0038,
+    span_err!(
+        tcx.sess, span, E0038,
         "the trait `{}` cannot be made into an object",
         tcx.item_path_str(trait_def_id));
 
@@ -402,7 +392,17 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
             let self_ty = trait_ref.self_ty();
             let all_types = &trait_ref.substs().types;
             if all_types.references_error() {
-            } else if all_types.needs_infer() {
+            } else {
+                // Typically, this ambiguity should only happen if
+                // there are unresolved type inference variables
+                // (otherwise it would suggest a coherence
+                // failure). But given #21974 that is not necessarily
+                // the case -- we can have multiple where clauses that
+                // are only distinguished by a region, which results
+                // in an ambiguity even when all types are fully
+                // known, since we don't dispatch based on region
+                // relationships.
+
                 // This is kind of a hack: it frequently happens that some earlier
                 // error prevents types from being fully inferred, and then we get
                 // a bunch of uninteresting errors saying something like "<generic
@@ -430,16 +430,6 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                         note_obligation_cause(infcx, obligation);
                     }
                 }
-            } else if !infcx.tcx.sess.has_errors() {
-                // Ambiguity. Coherence should have reported an error.
-                infcx.tcx.sess.span_bug(
-                    obligation.cause.span,
-                    &format!(
-                        "coherence failed to report ambiguity: \
-                         cannot locate the impl of the trait `{}` for \
-                         the type `{}`",
-                        trait_ref,
-                        self_ty));
             }
         }
 
@@ -491,10 +481,6 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
     let tcx = infcx.tcx;
     match *cause_code {
         ObligationCauseCode::MiscObligation => { }
-        ObligationCauseCode::RFC1214(ref subcode) => {
-            tcx.sess.note_rfc_1214(cause_span);
-            note_obligation_cause_code(infcx, predicate, cause_span, subcode);
-        }
         ObligationCauseCode::SliceOrArrayElem => {
             tcx.sess.fileline_note(
                 cause_span,
index d4e6f693d965d79c7e008948975e912924bdaca1..b93961f1aa9d2400e5edb84884db26afc53a32e4 100644 (file)
 use super::is_object_safe;
 use super::FulfillmentError;
 use super::ObligationCause;
-use super::ObligationCauseCode;
 use super::PredicateObligation;
 use super::project;
-use super::RFC1214Warning;
 use super::select::SelectionContext;
 use super::Unimplemented;
 use super::util::predicate_for_builtin_bound;
 
 pub struct FulfilledPredicates<'tcx> {
-    set: FnvHashSet<(RFC1214Warning, ty::Predicate<'tcx>)>
+    set: FnvHashSet<ty::Predicate<'tcx>>
 }
 
 /// The fulfillment context is used to drive trait resolution.  It
@@ -194,9 +192,7 @@ pub fn register_predicate_obligation<'a>(&mut self,
 
         assert!(!obligation.has_escaping_regions());
 
-        let w = RFC1214Warning(obligation.cause.code.is_rfc1214());
-
-        if self.is_duplicate_or_add(infcx.tcx, w, &obligation.predicate) {
+        if self.is_duplicate_or_add(infcx.tcx, &obligation.predicate) {
             debug!("register_predicate({:?}) -- already seen, skip", obligation);
             return;
         }
@@ -261,7 +257,6 @@ pub fn pending_obligations(&self) -> &[PredicateObligation<'tcx>] {
 
     fn is_duplicate_or_add(&mut self,
                            tcx: &ty::ctxt<'tcx>,
-                           w: RFC1214Warning,
                            predicate: &ty::Predicate<'tcx>)
                            -> bool {
         // This is a kind of dirty hack to allow us to avoid "rederiving"
@@ -276,12 +271,10 @@ fn is_duplicate_or_add(&mut self,
         // evaluating the 'nested obligations'.  This cache lets us
         // skip those.
 
-        let will_warn_due_to_rfc1214 = w.0;
-        let errors_will_be_reported = self.errors_will_be_reported && !will_warn_due_to_rfc1214;
-        if errors_will_be_reported && predicate.is_global() {
-            tcx.fulfilled_predicates.borrow_mut().is_duplicate_or_add(w, predicate)
+        if self.errors_will_be_reported && predicate.is_global() {
+            tcx.fulfilled_predicates.borrow_mut().is_duplicate_or_add(predicate)
         } else {
-            self.duplicate_set.is_duplicate_or_add(w, predicate)
+            self.duplicate_set.is_duplicate_or_add(predicate)
         }
     }
 
@@ -496,12 +489,8 @@ fn process_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
         }
 
         ty::Predicate::WellFormed(ty) => {
-            let rfc1214 = match obligation.cause.code {
-                ObligationCauseCode::RFC1214(_) => true,
-                _ => false,
-            };
             match ty::wf::obligations(selcx.infcx(), obligation.cause.body_id,
-                                      ty, obligation.cause.span, rfc1214) {
+                                      ty, obligation.cause.span) {
                 Some(obligations) => {
                     new_obligations.extend(obligations);
                     true
@@ -539,13 +528,11 @@ pub fn new() -> FulfilledPredicates<'tcx> {
         }
     }
 
-    pub fn is_duplicate(&self, w: RFC1214Warning, p: &ty::Predicate<'tcx>) -> bool {
-        let key = (w, p.clone());
-        self.set.contains(&key)
+    pub fn is_duplicate(&self, key: &ty::Predicate<'tcx>) -> bool {
+        self.set.contains(key)
     }
 
-    fn is_duplicate_or_add(&mut self, w: RFC1214Warning, p: &ty::Predicate<'tcx>) -> bool {
-        let key = (w, p.clone());
-        !self.set.insert(key)
+    fn is_duplicate_or_add(&mut self, key: &ty::Predicate<'tcx>) -> bool {
+        !self.set.insert(key.clone())
     }
 }
index 691bac0cef865f82c6cde00f92074961e1018226..255680465ca7fa4860c25bb2f2cebeb56b28fecb 100644 (file)
@@ -106,9 +106,6 @@ pub enum ObligationCauseCode<'tcx> {
     /// Not well classified or should be obvious from span.
     MiscObligation,
 
-    /// Obligation that triggers warning until RFC 1214 is fully in place.
-    RFC1214(Rc<ObligationCauseCode<'tcx>>),
-
     /// This is the trait reference from the given projection
     SliceOrArrayElem,
 
@@ -554,24 +551,6 @@ pub fn dummy() -> ObligationCause<'tcx> {
     }
 }
 
-/// This marker is used in some caches to record whether the
-/// predicate, if it is found to be false, will yield a warning (due
-/// to RFC1214) or an error. We separate these two cases in the cache
-/// so that if we see the same predicate twice, first resulting in a
-/// warning, and next resulting in an error, we still report the
-/// error, rather than considering it a duplicate.
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
-pub struct RFC1214Warning(bool);
-
-impl<'tcx> ObligationCauseCode<'tcx> {
-    pub fn is_rfc1214(&self) -> bool {
-        match *self {
-            ObligationCauseCode::RFC1214(..) => true,
-            _ => false,
-        }
-    }
-}
-
 impl<'tcx, N> Vtable<'tcx, N> {
     pub fn nested_obligations(self) -> Vec<N> {
         match self {
index 0b0f6c0b998fc584dfe5cb6fe3ae0d9f7682a521..b0215675fca815bbf3cc670a8c82028790a90ce3 100644 (file)
@@ -26,7 +26,6 @@
 use super::{SelectionError, Unimplemented, OutputTypeParameterMismatch};
 use super::{ObjectCastObligation, Obligation};
 use super::TraitNotObjectSafe;
-use super::RFC1214Warning;
 use super::Selection;
 use super::SelectionResult;
 use super::{VtableBuiltin, VtableImpl, VtableParam, VtableClosure,
@@ -463,8 +462,7 @@ fn evaluate_predicate_recursively<'o>(&mut self,
         // have been proven elsewhere. This cache only contains
         // predicates that are global in scope and hence unaffected by
         // the current environment.
-        let w = RFC1214Warning(false);
-        if self.tcx().fulfilled_predicates.borrow().is_duplicate(w, &obligation.predicate) {
+        if self.tcx().fulfilled_predicates.borrow().is_duplicate(&obligation.predicate) {
             return EvaluatedToOk;
         }
 
@@ -485,8 +483,7 @@ fn evaluate_predicate_recursively<'o>(&mut self,
 
             ty::Predicate::WellFormed(ty) => {
                 match ty::wf::obligations(self.infcx, obligation.cause.body_id,
-                                          ty, obligation.cause.span,
-                                          obligation.cause.code.is_rfc1214()) {
+                                          ty, obligation.cause.span) {
                     Some(obligations) =>
                         self.evaluate_predicates_recursively(previous_stack, obligations.iter()),
                     None =>
@@ -2906,22 +2903,11 @@ fn derived_cause(&self,
         // chain. Ideally, we should have a way to configure this either
         // by using -Z verbose or just a CLI argument.
         if obligation.recursion_depth >= 0 {
-            let derived_code = match obligation.cause.code {
-                ObligationCauseCode::RFC1214(ref base_code) => {
-                    let derived_cause = DerivedObligationCause {
-                        parent_trait_ref: obligation.predicate.to_poly_trait_ref(),
-                        parent_code: base_code.clone(),
-                    };
-                    ObligationCauseCode::RFC1214(Rc::new(variant(derived_cause)))
-                }
-                _ => {
-                    let derived_cause = DerivedObligationCause {
-                        parent_trait_ref: obligation.predicate.to_poly_trait_ref(),
-                        parent_code: Rc::new(obligation.cause.code.clone())
-                    };
-                    variant(derived_cause)
-                }
+            let derived_cause = DerivedObligationCause {
+                parent_trait_ref: obligation.predicate.to_poly_trait_ref(),
+                parent_code: Rc::new(obligation.cause.code.clone())
             };
+            let derived_code = variant(derived_cause);
             ObligationCause::new(obligation.cause.span, obligation.cause.body_id, derived_code)
         } else {
             obligation.cause.clone()
index 20e98821ca3afc3a062e1401a84d1301c4a2e08f..308883cf063df723e002e90db60c731477d156f9 100644 (file)
@@ -2114,6 +2114,10 @@ pub fn expr_is_lval(&self, expr: &hir::Expr) -> bool {
                 }
             }
 
+            hir::ExprType(ref e, _) => {
+                self.expr_is_lval(e)
+            }
+
             hir::ExprUnary(hir::UnDeref, _) |
             hir::ExprField(..) |
             hir::ExprTupField(..) |
index ea092ed977edaa11f044c618c8a20402a8e01d64..7752367febb19c6fdbaca3212af2faf1c556df55 100644 (file)
@@ -53,12 +53,6 @@ pub enum Component<'tcx> {
     // them. This gives us room to improve the regionck reasoning in
     // the future without breaking backwards compat.
     EscapingProjection(Vec<Component<'tcx>>),
-
-    // This is a temporary marker indicating "outlives components"
-    // that are due to the new rules introduced by RFC 1214.  For the
-    // time being, violations of these requirements generally induce
-    // warnings, not errors.
-    RFC1214(Vec<Component<'tcx>>),
 }
 
 /// Returns all the things that must outlive `'a` for the condition
@@ -124,20 +118,6 @@ fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
             }
         }
 
-        // Bare functions and traits are both binders. In the RFC,
-        // this means we would add the bound regions to the "bound
-        // regions list".  In our representation, no such list is
-        // maintained explicitly, because bound regions themselves can
-        // be readily identified. However, because the outlives
-        // relation did not used to be applied to fn/trait-object
-        // arguments, we wrap the resulting components in an RFC1214
-        // wrapper so we can issue warnings.
-        ty::TyBareFn(..) | ty::TyTrait(..) => {
-            // OutlivesFunction, OutlivesObject, OutlivesFragment
-            let subcomponents = capture_components(infcx, ty);
-            out.push(Component::RFC1214(subcomponents));
-        }
-
         // OutlivesTypeParameterEnv -- the actual checking that `X:'a`
         // is implied by the environment is done in regionck.
         ty::TyParam(p) => {
@@ -202,7 +182,15 @@ fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
         ty::TyRawPtr(..) |      // ...
         ty::TyRef(..) |         // OutlivesReference
         ty::TyTuple(..) |       // ...
+        ty::TyBareFn(..) |      // OutlivesFunction (*)
+        ty::TyTrait(..) |       // OutlivesObject, OutlivesFragment (*)
         ty::TyError => {
+            // (*) Bare functions and traits are both binders. In the
+            // RFC, this means we would add the bound regions to the
+            // "bound regions list".  In our representation, no such
+            // list is maintained explicitly, because bound regions
+            // themselves can be readily identified.
+
             push_region_constraints(out, ty.regions());
             for subty in ty.walk_shallow() {
                 compute_components(infcx, subty, out);
index 20534f72666db656f244e7282ce0e4000429efbd..d015711fa64db6851fee32fda897be091f746b47 100644 (file)
@@ -15,8 +15,6 @@
 use middle::traits;
 use middle::ty::{self, RegionEscape, ToPredicate, Ty};
 use std::iter::once;
-use std::mem;
-use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap::Span;
 use util::common::ErrorReported;
 pub fn obligations<'a,'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                             body_id: ast::NodeId,
                             ty: Ty<'tcx>,
-                            span: Span,
-                            rfc1214: bool)
+                            span: Span)
                             -> Option<Vec<traits::PredicateObligation<'tcx>>>
 {
     let mut wf = WfPredicates { infcx: infcx,
                                 body_id: body_id,
                                 span: span,
-                                out: vec![],
-                                rfc1214: rfc1214 };
+                                out: vec![] };
     if wf.compute(ty) {
         debug!("wf::obligations({:?}, body_id={:?}) = {:?}", ty, body_id, wf.out);
         let result = wf.normalize();
@@ -56,12 +52,10 @@ pub fn obligations<'a,'tcx>(infcx: &InferCtxt<'a, 'tcx>,
 pub fn trait_obligations<'a,'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                                   body_id: ast::NodeId,
                                   trait_ref: &ty::TraitRef<'tcx>,
-                                  span: Span,
-                                  rfc1214: bool)
+                                  span: Span)
                                   -> Vec<traits::PredicateObligation<'tcx>>
 {
-    let mut wf = WfPredicates { infcx: infcx, body_id: body_id, span: span,
-                                out: vec![], rfc1214: rfc1214 };
+    let mut wf = WfPredicates { infcx: infcx, body_id: body_id, span: span, out: vec![] };
     wf.compute_trait_ref(trait_ref);
     wf.normalize()
 }
@@ -69,12 +63,10 @@ pub fn trait_obligations<'a,'tcx>(infcx: &InferCtxt<'a, 'tcx>,
 pub fn predicate_obligations<'a,'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                                       body_id: ast::NodeId,
                                       predicate: &ty::Predicate<'tcx>,
-                                      span: Span,
-                                      rfc1214: bool)
+                                      span: Span)
                                       -> Vec<traits::PredicateObligation<'tcx>>
 {
-    let mut wf = WfPredicates { infcx: infcx, body_id: body_id, span: span,
-                                out: vec![], rfc1214: rfc1214 };
+    let mut wf = WfPredicates { infcx: infcx, body_id: body_id, span: span, out: vec![] };
 
     // (*) ok to skip binders, because wf code is prepared for it
     match *predicate {
@@ -150,7 +142,7 @@ pub fn implied_bounds<'a,'tcx>(
         // than the ultimate set. (Note: normally there won't be
         // unresolved inference variables here anyway, but there might be
         // during typeck under some circumstances.)
-        let obligations = obligations(infcx, body_id, ty, span, false).unwrap_or(vec![]);
+        let obligations = obligations(infcx, body_id, ty, span).unwrap_or(vec![]);
 
         // From the full set of obligations, just filter down to the
         // region relationships.
@@ -223,8 +215,6 @@ fn implied_bounds_from_components<'tcx>(sub_region: ty::Region,
                     vec!(),
                 Component::UnresolvedInferenceVariable(..) =>
                     vec!(),
-                Component::RFC1214(components) =>
-                    implied_bounds_from_components(sub_region, components),
             }
         })
         .collect()
@@ -235,24 +225,11 @@ struct WfPredicates<'a,'tcx:'a> {
     body_id: ast::NodeId,
     span: Span,
     out: Vec<traits::PredicateObligation<'tcx>>,
-    rfc1214: bool
 }
 
 impl<'a,'tcx> WfPredicates<'a,'tcx> {
-    fn rfc1214<R,F:FnOnce(&mut WfPredicates<'a,'tcx>) -> R>(&mut self, f: F) -> R {
-        let b = mem::replace(&mut self.rfc1214, true);
-        let r = f(self);
-        self.rfc1214 = b;
-        r
-    }
-
     fn cause(&mut self, code: traits::ObligationCauseCode<'tcx>) -> traits::ObligationCause<'tcx> {
-        if !self.rfc1214 {
-            traits::ObligationCause::new(self.span, self.body_id, code)
-        } else {
-            let code = traits::ObligationCauseCode::RFC1214(Rc::new(code));
-            traits::ObligationCause::new(self.span, self.body_id, code)
-        }
+        traits::ObligationCause::new(self.span, self.body_id, code)
     }
 
     fn normalize(&mut self) -> Vec<traits::PredicateObligation<'tcx>> {
@@ -268,14 +245,6 @@ fn normalize(&mut self) -> Vec<traits::PredicateObligation<'tcx>> {
                 .collect()
     }
 
-    fn compute_rfc1214(&mut self, ty: Ty<'tcx>) {
-        let b = mem::replace(&mut self.rfc1214, true);
-        for subty in ty.walk().skip(1) {
-            self.compute(subty);
-        }
-        self.rfc1214 = b;
-    }
-
     /// Pushes the obligations required for `trait_ref` to be WF into
     /// `self.out`.
     fn compute_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>) {
@@ -329,21 +298,19 @@ fn compute(&mut self, ty0: Ty<'tcx>) -> bool {
 
                 ty::TySlice(subty) |
                 ty::TyArray(subty, _) => {
-                    self.rfc1214(|this| {
-                        if !subty.has_escaping_regions() {
-                            let cause = this.cause(traits::SliceOrArrayElem);
-                            match traits::trait_ref_for_builtin_bound(this.infcx.tcx,
-                                                                      ty::BoundSized,
-                                                                      subty) {
-                                Ok(trait_ref) => {
-                                    this.out.push(
-                                        traits::Obligation::new(cause,
-                                                                trait_ref.to_predicate()));
-                                }
-                                Err(ErrorReported) => { }
+                    if !subty.has_escaping_regions() {
+                        let cause = self.cause(traits::SliceOrArrayElem);
+                        match traits::trait_ref_for_builtin_bound(self.infcx.tcx,
+                                                                  ty::BoundSized,
+                                                                  subty) {
+                            Ok(trait_ref) => {
+                                self.out.push(
+                                    traits::Obligation::new(cause,
+                                                            trait_ref.to_predicate()));
                             }
+                            Err(ErrorReported) => { }
                         }
-                    })
+                    }
                 }
 
                 ty::TyBox(_) |
@@ -380,15 +347,16 @@ fn compute(&mut self, ty0: Ty<'tcx>) -> bool {
                 ty::TyClosure(..) => {
                     // the types in a closure are always the types of
                     // local variables (or possibly references to local
-                    // variables), which are separately checked w/r/t
-                    // WFedness.
+                    // variables), we'll walk those.
+                    //
+                    // (Though, local variables are probably not
+                    // needed, as they are separately checked w/r/t
+                    // WFedness.)
                 }
 
                 ty::TyBareFn(..) => {
-                    // process the bound types; because the old implicator
-                    // did not do this, go into RFC1214 mode.
-                    subtys.skip_current_subtree();
-                    self.compute_rfc1214(ty);
+                    // let the loop iterator into the argument/return
+                    // types appearing in the fn signature
                 }
 
                 ty::TyTrait(ref data) => {
@@ -407,11 +375,6 @@ fn compute(&mut self, ty0: Ty<'tcx>) -> bool {
                         traits::Obligation::new(
                             cause,
                             ty::Predicate::ObjectSafe(data.principal_def_id())));
-
-                    // process the bound types; because the old implicator
-                    // did not do this, go into RFC1214 mode.
-                    subtys.skip_current_subtree();
-                    self.compute_rfc1214(ty);
                 }
 
                 // Inference variables are the complicated case, since we don't
index 7b96db4bf0a3af87e3283dc5cd672b30c5303865..a8587e83736812314e8d66673e78cf38130da892 100644 (file)
@@ -102,13 +102,6 @@ pub fn span_err(&self, sp: Span, msg: &str) {
             None => self.diagnostic().span_err(sp, msg)
         }
     }
-    pub fn note_rfc_1214(&self, span: Span) {
-        self.span_note(
-            span,
-            &format!("this warning results from recent bug fixes and clarifications; \
-                      it will become a HARD ERROR in the next release. \
-                      See RFC 1214 for details."));
-    }
     pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) {
         match split_msg_into_multilines(msg) {
             Some(msg) => self.diagnostic().span_err_with_code(sp, &msg[..], code),
index b926f8b061e5836ad095d3b613c26eae02dff03c..6cba27fcf34063b214fb5cf1a7eab44ac30b0c71 100644 (file)
@@ -19,6 +19,7 @@ pub struct RPathConfig<'a> {
     pub out_filename: PathBuf,
     pub is_like_osx: bool,
     pub has_rpath: bool,
+    pub linker_is_gnu: bool,
     pub get_install_prefix_lib_path: &'a mut FnMut() -> PathBuf,
 }
 
@@ -36,6 +37,12 @@ pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {
     let libs = libs.into_iter().filter_map(|(_, l)| l).collect::<Vec<_>>();
     let rpaths = get_rpaths(config, &libs[..]);
     flags.extend_from_slice(&rpaths_to_flags(&rpaths[..]));
+
+    // Use DT_RUNPATH instead of DT_RPATH if available
+    if config.linker_is_gnu {
+        flags.push("-Wl,--enable-new-dtags".to_string());
+    }
+
     flags
 }
 
@@ -228,6 +235,7 @@ fn test_rpath_relative() {
                 used_crates: Vec::new(),
                 has_rpath: true,
                 is_like_osx: true,
+                linker_is_gnu: false,
                 out_filename: PathBuf::from("bin/rustc"),
                 get_install_prefix_lib_path: &mut || panic!(),
             };
@@ -241,6 +249,7 @@ fn test_rpath_relative() {
                 get_install_prefix_lib_path: &mut || panic!(),
                 has_rpath: true,
                 is_like_osx: false,
+                linker_is_gnu: true,
             };
             let res = get_rpath_relative_to_output(config,
                                                    Path::new("lib/libstd.so"));
index a5df0b94b337400334ac91578659f89d157e794c..2532882d0127d22721541632b919ea8e759ad056 100644 (file)
@@ -234,6 +234,7 @@ pub enum SawExprComponent<'a> {
         SawExprUnary(hir::UnOp),
         SawExprLit(ast::Lit_),
         SawExprCast,
+        SawExprType,
         SawExprIf,
         SawExprWhile,
         SawExprMatch,
@@ -262,6 +263,7 @@ fn saw_expr<'a>(node: &'a Expr_) -> SawExprComponent<'a> {
             ExprUnary(op, _)         => SawExprUnary(op),
             ExprLit(ref lit)         => SawExprLit(lit.node.clone()),
             ExprCast(..)             => SawExprCast,
+            ExprType(..)             => SawExprType,
             ExprIf(..)               => SawExprIf,
             ExprWhile(..)            => SawExprWhile,
             ExprLoop(_, id)          => SawExprLoop(id.map(|id| id.name.as_str())),
index 784428cc114dc0cd9e7dba13dd0dd4e416aac3df..5da679c3495c5539406d291f636f2fe3d2f85b79 100644 (file)
@@ -1043,6 +1043,9 @@ pub fn noop_fold_expr<T: Folder>(Expr { id, node, span, attrs }: Expr, folder: &
             ExprCast(expr, ty) => {
                 ExprCast(folder.fold_expr(expr), folder.fold_ty(ty))
             }
+            ExprType(expr, ty) => {
+                ExprType(folder.fold_expr(expr), folder.fold_ty(ty))
+            }
             ExprAddrOf(m, ohs) => ExprAddrOf(m, folder.fold_expr(ohs)),
             ExprIf(cond, tr, fl) => {
                 ExprIf(folder.fold_expr(cond),
index 6b2664af60ba5cd3bdf998321199b3396bdf68ee..d079024bc96c4221b451490dccd587c12668604a 100644 (file)
@@ -737,6 +737,7 @@ pub enum Expr_ {
     ExprLit(P<Lit>),
     /// A cast (`foo as f64`)
     ExprCast(P<Expr>, P<Ty>),
+    ExprType(P<Expr>, P<Ty>),
     /// An `if` block, with an optional else block
     ///
     /// `if expr { block } else { expr }`
index 13d7e81cc6e0126f1bb7578e79434edb05d0b930..03b021cfa6395aed86e8ee1bd5daecccd20e0594 100644 (file)
@@ -732,7 +732,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
             visitor.visit_expr(subexpression)
         }
         ExprLit(_) => {}
-        ExprCast(ref subexpression, ref typ) => {
+        ExprCast(ref subexpression, ref typ) | ExprType(ref subexpression, ref typ) => {
             visitor.visit_expr(subexpression);
             visitor.visit_ty(typ)
         }
index 136c25f425ef4e2b35a952d5f54dbcccf6f7fa21..52e771bd5c37c02826f5533295d3bcd147f1308b 100644 (file)
@@ -1128,6 +1128,10 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                 let expr = lower_expr(lctx, expr);
                 hir::ExprCast(expr, lower_ty(lctx, ty))
             }
+            ExprType(ref expr, ref ty) => {
+                let expr = lower_expr(lctx, expr);
+                hir::ExprType(expr, lower_ty(lctx, ty))
+            }
             ExprAddrOf(m, ref ohs) => {
                 let m = lower_mutability(lctx, m);
                 let ohs = lower_expr(lctx, ohs);
index 9ac0e65cba33b051e841e38f4648dc6c02b2e247..f1b963bf11ddbeedb66f1fa96c88ca3576d9c317 100644 (file)
@@ -335,7 +335,8 @@ fn needs_parentheses(expr: &hir::Expr) -> bool {
         hir::ExprBinary(..) |
         hir::ExprClosure(..) |
         hir::ExprAssignOp(..) |
-        hir::ExprCast(..) => true,
+        hir::ExprCast(..) |
+        hir::ExprType(..) => true,
         _ => false,
     }
 }
@@ -1353,6 +1354,11 @@ pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> {
                 try!(self.word_space("as"));
                 try!(self.print_type(&**ty));
             }
+            hir::ExprType(ref expr, ref ty) => {
+                try!(self.print_expr(&**expr));
+                try!(self.word_space(":"));
+                try!(self.print_type(&**ty));
+            }
             hir::ExprIf(ref test, ref blk, ref elseopt) => {
                 try!(self.print_if(&**test, &**blk, elseopt.as_ref().map(|e| &**e)));
             }
index b8750cccb4b729d7c4f78bb21a4c121fdbaddc25..18a3a96069e19d8fcf7bd08bf45399ab239dabbb 100644 (file)
@@ -319,6 +319,7 @@ fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
                 }
                 ast::ExprUnary(_, ref x) |
                 ast::ExprCast(ref x, _) |
+                ast::ExprType(ref x, _) |
                 ast::ExprField(ref x, _) |
                 ast::ExprTupField(ref x, _) |
                 ast::ExprIndex(ref x, _) => {
index 8dcaa4b5064c18095c2ceeb61c48edb37f11b0c3..ebb0caa0dfae22a2bfa04f8b5b95c0a91a580187 100644 (file)
@@ -2012,32 +2012,6 @@ pub fn LLVMDICompositeTypeSetTypeArray(Builder: DIBuilderRef,
     pub fn LLVMIsAAllocaInst(value_ref: ValueRef) -> ValueRef;
     pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef;
 
-    pub fn LLVMInitializeX86TargetInfo();
-    pub fn LLVMInitializeX86Target();
-    pub fn LLVMInitializeX86TargetMC();
-    pub fn LLVMInitializeX86AsmPrinter();
-    pub fn LLVMInitializeX86AsmParser();
-    pub fn LLVMInitializeARMTargetInfo();
-    pub fn LLVMInitializeARMTarget();
-    pub fn LLVMInitializeARMTargetMC();
-    pub fn LLVMInitializeARMAsmPrinter();
-    pub fn LLVMInitializeARMAsmParser();
-    pub fn LLVMInitializeAArch64TargetInfo();
-    pub fn LLVMInitializeAArch64Target();
-    pub fn LLVMInitializeAArch64TargetMC();
-    pub fn LLVMInitializeAArch64AsmPrinter();
-    pub fn LLVMInitializeAArch64AsmParser();
-    pub fn LLVMInitializeMipsTargetInfo();
-    pub fn LLVMInitializeMipsTarget();
-    pub fn LLVMInitializeMipsTargetMC();
-    pub fn LLVMInitializeMipsAsmPrinter();
-    pub fn LLVMInitializeMipsAsmParser();
-    pub fn LLVMInitializePowerPCTargetInfo();
-    pub fn LLVMInitializePowerPCTarget();
-    pub fn LLVMInitializePowerPCTargetMC();
-    pub fn LLVMInitializePowerPCAsmPrinter();
-    pub fn LLVMInitializePowerPCAsmParser();
-
     pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: *const c_char) -> bool;
     pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
                                        CPU: *const c_char,
@@ -2145,6 +2119,53 @@ pub fn LLVMRustSetDataLayoutFromTargetMachine(M: ModuleRef,
     pub fn LLVMRustGetModuleDataLayout(M: ModuleRef) -> TargetDataRef;
 }
 
+#[cfg(have_component_x86)]
+extern {
+    pub fn LLVMInitializeX86TargetInfo();
+    pub fn LLVMInitializeX86Target();
+    pub fn LLVMInitializeX86TargetMC();
+    pub fn LLVMInitializeX86AsmPrinter();
+    pub fn LLVMInitializeX86AsmParser();
+}
+#[cfg(have_component_arm)]
+extern {
+    pub fn LLVMInitializeARMTargetInfo();
+    pub fn LLVMInitializeARMTarget();
+    pub fn LLVMInitializeARMTargetMC();
+    pub fn LLVMInitializeARMAsmPrinter();
+    pub fn LLVMInitializeARMAsmParser();
+}
+#[cfg(have_component_aarch64)]
+extern {
+    pub fn LLVMInitializeAArch64TargetInfo();
+    pub fn LLVMInitializeAArch64Target();
+    pub fn LLVMInitializeAArch64TargetMC();
+    pub fn LLVMInitializeAArch64AsmPrinter();
+    pub fn LLVMInitializeAArch64AsmParser();
+}
+#[cfg(have_component_mips)]
+extern {
+    pub fn LLVMInitializeMipsTargetInfo();
+    pub fn LLVMInitializeMipsTarget();
+    pub fn LLVMInitializeMipsTargetMC();
+    pub fn LLVMInitializeMipsAsmPrinter();
+    pub fn LLVMInitializeMipsAsmParser();
+}
+#[cfg(have_component_powerpc)]
+extern {
+    pub fn LLVMInitializePowerPCTargetInfo();
+    pub fn LLVMInitializePowerPCTarget();
+    pub fn LLVMInitializePowerPCTargetMC();
+    pub fn LLVMInitializePowerPCAsmPrinter();
+    pub fn LLVMInitializePowerPCAsmParser();
+}
+#[cfg(have_component_pnacl)]
+extern {
+    pub fn LLVMInitializePNaClTargetInfo();
+    pub fn LLVMInitializePNaClTarget();
+    pub fn LLVMInitializePNaClTargetMC();
+}
+
 // LLVM requires symbols from this library, but apparently they're not printed
 // during llvm-config?
 #[cfg(windows)]
@@ -2358,6 +2379,20 @@ fn init() { }
     init_target!(have_component_aarch64 AArch64);
     init_target!(have_component_arm ARM);
     init_target!(have_component_x86 X86);
+
+    // PNaCl doesn't provide some of the optional target components, so we
+    // manually initialize it here.
+    #[cfg(have_component_pnacl)]
+    fn init_pnacl() {
+        unsafe {
+            LLVMInitializePNaClTargetInfo();
+            LLVMInitializePNaClTarget();
+            LLVMInitializePNaClTargetMC();
+        }
+    }
+    #[cfg(not(have_component_pnacl))]
+    fn init_pnacl() { }
+    init_pnacl();
 }
 
 // The module containing the native LLVM dependencies, generated by the build system
index d1455e7016524117b4a0fe86831890602d543686..5cb12627d6ba882eac4e03f2925a4d2f45bbe0e5 100644 (file)
@@ -320,6 +320,8 @@ fn make_mirror<'a>(self, cx: &mut Cx<'a, 'tcx>) -> Expr<'tcx> {
                                   name: Field::new(index.node as usize) },
             hir::ExprCast(ref source, _) =>
                 ExprKind::Cast { source: source.to_ref() },
+            hir::ExprType(ref source, _) =>
+                return source.make_mirror(cx),
             hir::ExprBox(ref value) =>
                 ExprKind::Box { value: value.to_ref() },
             hir::ExprVec(ref fields) =>
index 975323375f18effc1e6bfe24af67b5a78021f4e6..fb79f804932f807957b03657f0b89256c9a9586a 100644 (file)
@@ -1054,6 +1054,7 @@ fn link_args(cmd: &mut Linker,
             out_filename: out_filename.to_path_buf(),
             has_rpath: sess.target.target.options.has_rpath,
             is_like_osx: sess.target.target.options.is_like_osx,
+            linker_is_gnu: sess.target.target.options.linker_is_gnu,
             get_install_prefix_lib_path: &mut get_install_prefix_lib_path,
         };
         cmd.args(&rpath::get_rpath_flags(&mut rpath_config));
index 038e699a043ab4d755c17484959defab7227ed98..0fafe08178a273a725b3752e5982baacc519adba 100644 (file)
@@ -1003,6 +1003,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             try!(const_fn_call(cx, MethodCallKey(method_call),
                                method_did, &arg_vals, param_substs, trueconst))
         },
+        hir::ExprType(ref e, _) => try!(const_expr(cx, &**e, param_substs, fn_args, trueconst)).0,
         hir::ExprBlock(ref block) => {
             match block.expr {
                 Some(ref expr) => try!(const_expr(
index 231dec276d99cdc1705384fb00b34d02b87f4e89..237d31c47783d91059fbf2635af13f99eec1c69d 100644 (file)
@@ -320,6 +320,7 @@ fn walk_expr(cx: &CrateContext,
         hir::ExprPath(..) => {}
 
         hir::ExprCast(ref sub_exp, _)     |
+        hir::ExprType(ref sub_exp, _) |
         hir::ExprAddrOf(_, ref sub_exp)  |
         hir::ExprField(ref sub_exp, _) |
         hir::ExprTupField(ref sub_exp, _) =>
index d2cbb9892f6a60834390a242125d8b0c26c14179..ecf54cde9f63a7ba5ce37df816f4399b3a756d96 100644 (file)
@@ -656,6 +656,9 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let _icx = push_ctxt("trans_datum_unadjusted");
 
     match expr.node {
+        hir::ExprType(ref e, _) => {
+            trans(bcx, &**e)
+        }
         hir::ExprPath(..) => {
             trans_def(bcx, expr, bcx.def(expr.id))
         }
@@ -941,6 +944,9 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         hir::ExprBreak(label_opt) => {
             controlflow::trans_break(bcx, expr, label_opt.map(|l| l.node.name))
         }
+        hir::ExprType(ref e, _) => {
+            trans_into(bcx, &**e, Ignore)
+        }
         hir::ExprAgain(label_opt) => {
             controlflow::trans_cont(bcx, expr, label_opt.map(|l| l.node.name))
         }
@@ -1064,6 +1070,9 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     debuginfo::set_source_location(bcx.fcx, expr.id, expr.span);
 
     match expr.node {
+        hir::ExprType(ref e, _) => {
+            trans_into(bcx, &**e, dest)
+        }
         hir::ExprPath(..) => {
             trans_def_dps_unadjusted(bcx, expr, bcx.def(expr.id), dest)
         }
@@ -2601,6 +2610,10 @@ fn expr_kind(tcx: &ty::ctxt, expr: &hir::Expr) -> ExprKind {
             }
         }
 
+        hir::ExprType(ref expr, _) => {
+            expr_kind(tcx, expr)
+        }
+
         hir::ExprUnary(hir::UnDeref, _) |
         hir::ExprField(..) |
         hir::ExprTupField(..) |
index d7026b722af36a768de8d1fc285e7a62418407e1..265969c52b39d3608b2078658272f3f2bd8b8d32 100644 (file)
@@ -9,14 +9,18 @@
 // except according to those terms.
 
 use llvm::BasicBlockRef;
+use middle::infer;
+use middle::ty;
 use rustc::mir::repr as mir;
 use trans::adt;
 use trans::base;
 use trans::build;
-use trans::common::Block;
+use trans::common::{self, Block};
 use trans::debuginfo::DebugLoc;
+use trans::type_of;
 
 use super::MirContext;
+use super::operand::OperandValue::{FatPtr, Immediate, Ref};
 
 impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
     pub fn trans_block(&mut self, bb: mir::BasicBlock) {
@@ -101,29 +105,65 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
                 base::build_return_block(bcx.fcx, bcx, return_ty, DebugLoc::None);
             }
 
-            mir::Terminator::Call { .. } => {
-                unimplemented!()
-                //let llbb = unimplemented!(); // self.make_landing_pad(panic_bb);
-                //
-                //let tr_dest = self.trans_lvalue(bcx, &data.destination);
-                //
-                //// Create the callee. This will always be a fn
-                //// ptr and hence a kind of scalar.
-                //let callee = self.trans_operand(bcx, &data.func);
-                //
-                //// Process the arguments.
-                //
-                //let args = unimplemented!();
-                //
-                //callee::trans_call_inner(bcx,
-                //                         DebugLoc::None,
-                //                         |bcx, _| Callee {
-                //                             bcx: bcx,
-                //                             data: CalleeData::Fn(callee.llval),
-                //                             ty: callee.ty,
-                //                         },
-                //                         args,
-                //                         Some(Dest::SaveIn(tr_dest.llval)));
+            mir::Terminator::Call { ref data, targets } => {
+                // The location we'll write the result of the call into.
+                let call_dest = self.trans_lvalue(bcx, &data.destination);
+
+                // Create the callee. This will always be a fn
+                // ptr and hence a kind of scalar.
+                let callee = self.trans_operand(bcx, &data.func);
+                let ret_ty = if let ty::TyBareFn(_, ref f) = callee.ty.sty {
+                    let sig = bcx.tcx().erase_late_bound_regions(&f.sig);
+                    let sig = infer::normalize_associated_type(bcx.tcx(), &sig);
+                    sig.output
+                } else {
+                    panic!("trans_block: expected TyBareFn as callee");
+                };
+
+                // The arguments we'll be passing
+                let mut llargs = vec![];
+
+                // Does the fn use an outptr? If so, that's the first arg.
+                if let ty::FnConverging(ret_ty) = ret_ty {
+                    if type_of::return_uses_outptr(bcx.ccx(), ret_ty) {
+                        llargs.push(call_dest.llval);
+                    }
+                }
+
+                // Process the rest of the args.
+                for arg in &data.args {
+                    let arg_op = self.trans_operand(bcx, arg);
+                    match arg_op.val {
+                        Ref(llval) | Immediate(llval) => llargs.push(llval),
+                        FatPtr(base, extra) => {
+                            // The two words in a fat ptr are passed separately
+                            llargs.push(base);
+                            llargs.push(extra);
+                        }
+                    }
+                }
+
+                // FIXME: Handle panics
+                //let panic_bb = self.llblock(targets.1);
+                //self.make_landing_pad(panic_bb);
+
+                // Do the actual call.
+                let (llret, b) = base::invoke(bcx,
+                                              callee.immediate(),
+                                              &llargs[..],
+                                              callee.ty,
+                                              DebugLoc::None);
+                bcx = b;
+
+                // Copy the return value into the destination.
+                if let ty::FnConverging(ret_ty) = ret_ty {
+                    if !type_of::return_uses_outptr(bcx.ccx(), ret_ty) &&
+                       !common::type_is_zero_size(bcx.ccx(), ret_ty) {
+                        base::store_ty(bcx, llret, call_dest.llval, ret_ty);
+                    }
+                }
+
+                build::Br(bcx, self.llblock(targets.0), DebugLoc::None)
             }
         }
     }
index feea38acdc7ef08d3eea278c103840fcb58bdc4c..98ae3071b87d22c3927dca80f286c65a2bd55802 100644 (file)
@@ -1136,7 +1136,7 @@ fn make_object_type<'tcx>(this: &AstConv<'tcx>,
         traits::astconv_object_safety_violations(tcx, principal.def_id());
     if !object_safety_violations.is_empty() {
         traits::report_object_safety_error(
-            tcx, span, principal.def_id(), object_safety_violations, false);
+            tcx, span, principal.def_id(), object_safety_violations);
         return tcx.types.err;
     }
 
index bddf0e9ffb0cb1d205aa00b2c8aff3f1e88010aa..c91f65814186415aff56d75cf376d4cf973d0c9d 100644 (file)
 pub mod demand;
 pub mod method;
 mod upvar;
-mod wf;
 mod wfcheck;
 mod cast;
 mod closure;
@@ -382,21 +381,6 @@ fn visit_item(&mut self, i: &'tcx hir::Item) {
     }
 }
 
-pub fn check_wf_old(ccx: &CrateCtxt) {
-    // If types are not well-formed, it leads to all manner of errors
-    // downstream, so stop reporting errors at this point.
-    ccx.tcx.sess.abort_if_new_errors(|| {
-        // FIXME(#25759). The new code below is much more reliable but (for now)
-        // only generates warnings. So as to ensure that we continue
-        // getting errors where we used to get errors, we run the old wf
-        // code first and abort if it encounters any errors. If no abort
-        // comes, we run the new code and issue warnings.
-        let krate = ccx.tcx.map.krate();
-        let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx);
-        krate.visit_all_items(&mut visit);
-    });
-}
-
 pub fn check_wf_new(ccx: &CrateCtxt) {
     ccx.tcx.sess.abort_if_new_errors(|| {
         let krate = ccx.tcx.map.krate();
@@ -2664,6 +2648,14 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     }
 }
 
+fn check_expr_eq_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
+                                expr: &'tcx hir::Expr,
+                                expected: Ty<'tcx>) {
+    check_expr_with_unifier(
+        fcx, expr, ExpectHasType(expected), NoPreference,
+        || demand::eqtype(fcx, expr.span, expected, fcx.expr_ty(expr)));
+}
+
 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                      expr: &'tcx hir::Expr,
                                      expected: Ty<'tcx>) {
@@ -3526,6 +3518,11 @@ fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
             deferred_cast_checks.push(cast_check);
         }
       }
+      hir::ExprType(ref e, ref t) => {
+        let typ = fcx.to_ty(&**t);
+        check_expr_eq_type(fcx, &**e, typ);
+        fcx.write_ty(id, typ);
+      }
       hir::ExprVec(ref args) => {
         let uty = expected.to_option(fcx).and_then(|uty| {
             match uty.sty {
index 8777e38bb71d8a69fe7e2526e7149ced530d4074..759d561a961b7dab66aa761a5bd9abea38b0fa86 100644 (file)
@@ -99,7 +99,6 @@
 use middle::ty::wf::ImpliedBound;
 
 use std::mem;
-use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap::Span;
 use rustc_front::intravisit::{self, Visitor};
@@ -426,8 +425,6 @@ fn code_to_origin(&self,
                       code: &traits::ObligationCauseCode<'tcx>)
                       -> SubregionOrigin<'tcx> {
         match *code {
-            traits::ObligationCauseCode::RFC1214(ref code) =>
-                infer::RFC1214Subregion(Rc::new(self.code_to_origin(span, sup_type, code))),
             traits::ObligationCauseCode::ReferenceOutlivesReferent(ref_type) =>
                 infer::ReferenceOutlivesReferent(ref_type, span),
             _ =>
@@ -1606,10 +1603,6 @@ fn components_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
                     origin.span(),
                     &format!("unresolved inference variable in outlives: {:?}", v));
             }
-            ty::outlives::Component::RFC1214(subcomponents) => {
-                let suborigin = infer::RFC1214Subregion(Rc::new(origin));
-                components_must_outlive(rcx, suborigin, subcomponents, region);
-            }
         }
     }
 }
diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs
deleted file mode 100644 (file)
index ee2845c..0000000
+++ /dev/null
@@ -1,673 +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.
-
-use astconv::AstConv;
-use check::{FnCtxt, Inherited, blank_fn_ctxt, regionck, wfcheck};
-use constrained_type_params::{identify_constrained_type_params, Parameter};
-use CrateCtxt;
-use middle::region;
-use middle::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace};
-use middle::traits;
-use middle::ty::{self, Ty};
-use middle::ty::fold::{TypeFolder, TypeFoldable, super_fold_ty};
-
-use std::cell::RefCell;
-use std::collections::HashSet;
-use syntax::ast;
-use syntax::codemap::{DUMMY_SP, Span};
-use syntax::parse::token::special_idents;
-
-use rustc_front::intravisit::{self, Visitor, FnKind};
-use rustc_front::hir;
-
-pub struct CheckTypeWellFormedVisitor<'ccx, 'tcx:'ccx> {
-    ccx: &'ccx CrateCtxt<'ccx, 'tcx>,
-    cache: HashSet<Ty<'tcx>>
-}
-
-impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
-    pub fn new(ccx: &'ccx CrateCtxt<'ccx, 'tcx>) -> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
-        CheckTypeWellFormedVisitor { ccx: ccx, cache: HashSet::new() }
-    }
-
-    fn tcx(&self) -> &ty::ctxt<'tcx> {
-        self.ccx.tcx
-    }
-
-    /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are
-    /// well-formed, meaning that they do not require any constraints not declared in the struct
-    /// definition itself. For example, this definition would be illegal:
-    ///
-    ///     struct Ref<'a, T> { x: &'a T }
-    ///
-    /// because the type did not declare that `T:'a`.
-    ///
-    /// We do this check as a pre-pass before checking fn bodies because if these constraints are
-    /// not included it frequently leads to confusing errors in fn bodies. So it's better to check
-    /// the types first.
-    fn check_item_well_formed(&mut self, item: &hir::Item) {
-        let ccx = self.ccx;
-        debug!("check_item_well_formed(it.id={}, it.name={})",
-               item.id,
-               ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(item.id)));
-
-        match item.node {
-            /// Right now we check that every default trait implementation
-            /// has an implementation of itself. Basically, a case like:
-            ///
-            /// `impl Trait for T {}`
-            ///
-            /// has a requirement of `T: Trait` which was required for default
-            /// method implementations. Although this could be improved now that
-            /// there's a better infrastructure in place for this, it's being left
-            /// for a follow-up work.
-            ///
-            /// Since there's such a requirement, we need to check *just* positive
-            /// implementations, otherwise things like:
-            ///
-            /// impl !Send for T {}
-            ///
-            /// won't be allowed unless there's an *explicit* implementation of `Send`
-            /// for `T`
-            hir::ItemImpl(_, hir::ImplPolarity::Positive, _, _, _, _) => {
-                self.check_impl(item);
-            }
-            hir::ItemImpl(_, hir::ImplPolarity::Negative, _, Some(_), _, _) => {
-                let item_def_id = ccx.tcx.map.local_def_id(item.id);
-                let trait_ref = ccx.tcx.impl_trait_ref(item_def_id).unwrap();
-                ccx.tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id);
-                match ccx.tcx.lang_items.to_builtin_kind(trait_ref.def_id) {
-                    Some(ty::BoundSend) | Some(ty::BoundSync) => {}
-                    Some(_) | None => {
-                        if !ccx.tcx.trait_has_default_impl(trait_ref.def_id) {
-                            wfcheck::error_192(ccx, item.span);
-                        }
-                    }
-                }
-            }
-            hir::ItemFn(..) => {
-                self.check_item_type(item);
-            }
-            hir::ItemStatic(..) => {
-                self.check_item_type(item);
-            }
-            hir::ItemConst(..) => {
-                self.check_item_type(item);
-            }
-            hir::ItemStruct(ref struct_def, ref ast_generics) => {
-                self.check_type_defn(item, |fcx| {
-                    vec![struct_variant(fcx, struct_def)]
-                });
-
-                self.check_variances_for_type_defn(item, ast_generics);
-            }
-            hir::ItemEnum(ref enum_def, ref ast_generics) => {
-                self.check_type_defn(item, |fcx| {
-                    enum_variants(fcx, enum_def)
-                });
-
-                self.check_variances_for_type_defn(item, ast_generics);
-            }
-            hir::ItemTrait(_, _, _, ref items) => {
-                let trait_predicates =
-                    ccx.tcx.lookup_predicates(ccx.tcx.map.local_def_id(item.id));
-                reject_non_type_param_bounds(ccx.tcx, item.span, &trait_predicates);
-                if ccx.tcx.trait_has_default_impl(ccx.tcx.map.local_def_id(item.id)) {
-                    if !items.is_empty() {
-                        wfcheck::error_380(ccx, item.span);
-                    }
-                }
-            }
-            _ => {}
-        }
-    }
-
-    fn with_fcx<F>(&mut self, item: &hir::Item, mut f: F) where
-        F: for<'fcx> FnMut(&mut CheckTypeWellFormedVisitor<'ccx, 'tcx>, &FnCtxt<'fcx, 'tcx>),
-    {
-        let ccx = self.ccx;
-        let item_def_id = ccx.tcx.map.local_def_id(item.id);
-        let type_scheme = ccx.tcx.lookup_item_type(item_def_id);
-        let type_predicates = ccx.tcx.lookup_predicates(item_def_id);
-        reject_non_type_param_bounds(ccx.tcx, item.span, &type_predicates);
-        let free_id_outlive = ccx.tcx.region_maps.item_extent(item.id);
-        let param_env = ccx.tcx.construct_parameter_environment(item.span,
-                                                                &type_scheme.generics,
-                                                                &type_predicates,
-                                                                free_id_outlive);
-        let tables = RefCell::new(ty::Tables::empty());
-        let inh = Inherited::new(ccx.tcx, &tables, param_env);
-        let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(type_scheme.ty), item.id);
-        f(self, &fcx);
-        fcx.select_all_obligations_or_error();
-        regionck::regionck_item(&fcx, item.id, item.span, &[]);
-    }
-
-    /// In a type definition, we check that to ensure that the types of the fields are well-formed.
-    fn check_type_defn<F>(&mut self, item: &hir::Item, mut lookup_fields: F) where
-        F: for<'fcx> FnMut(&FnCtxt<'fcx, 'tcx>) -> Vec<AdtVariant<'tcx>>,
-    {
-        self.with_fcx(item, |this, fcx| {
-            let variants = lookup_fields(fcx);
-            let mut bounds_checker = BoundsChecker::new(fcx,
-                                                        item.id,
-                                                        Some(&mut this.cache));
-            debug!("check_type_defn at bounds_checker.scope: {:?}", bounds_checker.scope);
-
-            for variant in &variants {
-                for field in &variant.fields {
-                    // Regions are checked below.
-                    bounds_checker.check_traits_in_ty(field.ty, field.span);
-                }
-
-                // For DST, all intermediate types must be sized.
-                if let Some((_, fields)) = variant.fields.split_last() {
-                    for field in fields {
-                        fcx.register_builtin_bound(
-                            field.ty,
-                            ty::BoundSized,
-                            traits::ObligationCause::new(field.span,
-                                                         fcx.body_id,
-                                                         traits::FieldSized));
-                    }
-                }
-            }
-
-            for field in variants.iter().flat_map(|v| v.fields.iter()) {
-                fcx.register_old_wf_obligation(field.ty, field.span, traits::MiscObligation);
-            }
-        });
-    }
-
-    fn check_item_type(&mut self,
-                       item: &hir::Item)
-    {
-        self.with_fcx(item, |this, fcx| {
-            let mut bounds_checker = BoundsChecker::new(fcx,
-                                                        item.id,
-                                                        Some(&mut this.cache));
-            debug!("check_item_type at bounds_checker.scope: {:?}", bounds_checker.scope);
-
-            let item_def_id = fcx.tcx().map.local_def_id(item.id);
-            let type_scheme = fcx.tcx().lookup_item_type(item_def_id);
-            let item_ty = fcx.instantiate_type_scheme(item.span,
-                                                      &fcx.inh
-                                                          .infcx
-                                                          .parameter_environment
-                                                          .free_substs,
-                                                      &type_scheme.ty);
-
-            bounds_checker.check_traits_in_ty(item_ty, item.span);
-        });
-    }
-
-    fn check_impl(&mut self,
-                  item: &hir::Item)
-    {
-        self.with_fcx(item, |this, fcx| {
-            let mut bounds_checker = BoundsChecker::new(fcx,
-                                                        item.id,
-                                                        Some(&mut this.cache));
-            debug!("check_impl at bounds_checker.scope: {:?}", bounds_checker.scope);
-
-            // Find the impl self type as seen from the "inside" --
-            // that is, with all type parameters converted from bound
-            // to free.
-            let self_ty = fcx.tcx().node_id_to_type(item.id);
-            let self_ty = fcx.instantiate_type_scheme(item.span,
-                                                      &fcx.inh
-                                                          .infcx
-                                                          .parameter_environment
-                                                          .free_substs,
-                                                      &self_ty);
-
-            bounds_checker.check_traits_in_ty(self_ty, item.span);
-
-            // Similarly, obtain an "inside" reference to the trait
-            // that the impl implements.
-            let trait_ref = match fcx.tcx().impl_trait_ref(fcx.tcx().map.local_def_id(item.id)) {
-                None => { return; }
-                Some(t) => { t }
-            };
-
-            let trait_ref = fcx.instantiate_type_scheme(item.span,
-                                                        &fcx.inh
-                                                            .infcx
-                                                            .parameter_environment
-                                                            .free_substs,
-                                                        &trait_ref);
-
-            // We are stricter on the trait-ref in an impl than the
-            // self-type.  In particular, we enforce region
-            // relationships. The reason for this is that (at least
-            // presently) "applying" an impl does not require that the
-            // application site check the well-formedness constraints on the
-            // trait reference. Instead, this is done at the impl site.
-            // Arguably this is wrong and we should treat the trait-reference
-            // the same way as we treat the self-type.
-            bounds_checker.check_trait_ref(&trait_ref, item.span);
-
-            let cause =
-                traits::ObligationCause::new(
-                    item.span,
-                    fcx.body_id,
-                    traits::ItemObligation(trait_ref.def_id));
-
-            // Find the supertrait bounds. This will add `int:Bar`.
-            let poly_trait_ref = ty::Binder(trait_ref);
-            let predicates = fcx.tcx().lookup_super_predicates(poly_trait_ref.def_id());
-            let predicates = predicates.instantiate_supertrait(fcx.tcx(), &poly_trait_ref);
-            let predicates = {
-                let selcx = &mut traits::SelectionContext::new(fcx.infcx());
-                traits::normalize(selcx, cause.clone(), &predicates)
-            };
-            for predicate in predicates.value.predicates {
-                fcx.register_predicate(traits::Obligation::new(cause.clone(), predicate));
-            }
-            for obligation in predicates.obligations {
-                fcx.register_predicate(obligation);
-            }
-        });
-    }
-
-    fn check_variances_for_type_defn(&self,
-                                     item: &hir::Item,
-                                     ast_generics: &hir::Generics)
-    {
-        let item_def_id = self.tcx().map.local_def_id(item.id);
-        let ty_predicates = self.tcx().lookup_predicates(item_def_id);
-        let variances = self.tcx().item_variances(item_def_id);
-
-        let mut constrained_parameters: HashSet<_> =
-            variances.types
-                     .iter_enumerated()
-                     .filter(|&(_, _, &variance)| variance != ty::Bivariant)
-                     .map(|(space, index, _)| self.param_ty(ast_generics, space, index))
-                     .map(|p| Parameter::Type(p))
-                     .collect();
-
-        identify_constrained_type_params(self.tcx(),
-                                         ty_predicates.predicates.as_slice(),
-                                         None,
-                                         &mut constrained_parameters);
-
-        for (space, index, _) in variances.types.iter_enumerated() {
-            let param_ty = self.param_ty(ast_generics, space, index);
-            if constrained_parameters.contains(&Parameter::Type(param_ty)) {
-                continue;
-            }
-            let span = self.ty_param_span(ast_generics, item, space, index);
-            self.report_bivariance(span, param_ty.name);
-        }
-
-        for (space, index, &variance) in variances.regions.iter_enumerated() {
-            if variance != ty::Bivariant {
-                continue;
-            }
-
-            assert_eq!(space, TypeSpace);
-            let span = ast_generics.lifetimes[index].lifetime.span;
-            let name = ast_generics.lifetimes[index].lifetime.name;
-            self.report_bivariance(span, name);
-        }
-    }
-
-    fn param_ty(&self,
-                ast_generics: &hir::Generics,
-                space: ParamSpace,
-                index: usize)
-                -> ty::ParamTy
-    {
-        let name = match space {
-            TypeSpace => ast_generics.ty_params[index].name,
-            SelfSpace => special_idents::type_self.name,
-            FnSpace => self.tcx().sess.bug("Fn space occupied?"),
-        };
-
-        ty::ParamTy { space: space, idx: index as u32, name: name }
-    }
-
-    fn ty_param_span(&self,
-                     ast_generics: &hir::Generics,
-                     item: &hir::Item,
-                     space: ParamSpace,
-                     index: usize)
-                     -> Span
-    {
-        match space {
-            TypeSpace => ast_generics.ty_params[index].span,
-            SelfSpace => item.span,
-            FnSpace => self.tcx().sess.span_bug(item.span, "Fn space occupied?"),
-        }
-    }
-
-    fn report_bivariance(&self,
-                         span: Span,
-                         param_name: ast::Name)
-    {
-        wfcheck::error_392(self.tcx(), span, param_name);
-
-        let suggested_marker_id = self.tcx().lang_items.phantom_data();
-        match suggested_marker_id {
-            Some(def_id) => {
-                self.tcx().sess.fileline_help(
-                    span,
-                    &format!("consider removing `{}` or using a marker such as `{}`",
-                             param_name,
-                             self.tcx().item_path_str(def_id)));
-            }
-            None => {
-                // no lang items, no help!
-            }
-        }
-    }
-}
-
-// Reject any predicates that do not involve a type parameter.
-fn reject_non_type_param_bounds<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                      span: Span,
-                                      predicates: &ty::GenericPredicates<'tcx>) {
-    for predicate in &predicates.predicates {
-        match predicate {
-            &ty::Predicate::Trait(ty::Binder(ref tr)) => {
-                let found_param = tr.input_types().iter()
-                                    .flat_map(|ty| ty.walk())
-                                    .any(is_ty_param);
-                if !found_param { report_bound_error(tcx, span, tr.self_ty() )}
-            }
-            &ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(ty, _))) => {
-                let found_param = ty.walk().any(|t| is_ty_param(t));
-                if !found_param { report_bound_error(tcx, span, ty) }
-            }
-            _ => {}
-        };
-    }
-
-    fn report_bound_error<'t>(tcx: &ty::ctxt<'t>,
-                          span: Span,
-                          bounded_ty: ty::Ty<'t>) {
-        span_err!(tcx.sess, span, E0193,
-            "cannot bound type `{}`, where clause \
-                bounds may only be attached to types involving \
-                type parameters",
-                bounded_ty)
-    }
-
-    fn is_ty_param(ty: ty::Ty) -> bool {
-        match &ty.sty {
-            &ty::TyParam(_) => true,
-            _ => false
-        }
-    }
-}
-
-fn reject_shadowing_type_parameters<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                          span: Span,
-                                          generics: &ty::Generics<'tcx>) {
-    let impl_params = generics.types.get_slice(subst::TypeSpace).iter()
-        .map(|tp| tp.name).collect::<HashSet<_>>();
-
-    for method_param in generics.types.get_slice(subst::FnSpace) {
-        if impl_params.contains(&method_param.name) {
-            wfcheck::error_194(tcx, span, method_param.name);
-        }
-    }
-}
-
-impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
-    fn visit_item(&mut self, i: &hir::Item) {
-        self.check_item_well_formed(i);
-        intravisit::walk_item(self, i);
-    }
-
-    fn visit_fn(&mut self,
-                fk: FnKind<'v>, fd: &'v hir::FnDecl,
-                b: &'v hir::Block, span: Span, id: ast::NodeId) {
-        match fk {
-            FnKind::Closure | FnKind::ItemFn(..) => {}
-            FnKind::Method(..) => {
-                match self.tcx().impl_or_trait_item(self.tcx().map.local_def_id(id)) {
-                    ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
-                        reject_shadowing_type_parameters(self.tcx(), span, &ty_method.generics)
-                    }
-                    _ => {}
-                }
-            }
-        }
-        intravisit::walk_fn(self, fk, fd, b, span)
-    }
-
-    fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) {
-        if let hir::MethodTraitItem(_, None) = trait_item.node {
-            match self.tcx().impl_or_trait_item(self.tcx().map.local_def_id(trait_item.id)) {
-                ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
-                    reject_non_type_param_bounds(
-                        self.tcx(),
-                        trait_item.span,
-                        &ty_method.predicates);
-                    reject_shadowing_type_parameters(
-                        self.tcx(),
-                        trait_item.span,
-                        &ty_method.generics);
-                }
-                _ => {}
-            }
-        }
-
-        intravisit::walk_trait_item(self, trait_item)
-    }
-}
-
-pub struct BoundsChecker<'cx,'tcx:'cx> {
-    fcx: &'cx FnCtxt<'cx,'tcx>,
-    span: Span,
-
-    scope: region::CodeExtent,
-
-    binding_count: usize,
-    cache: Option<&'cx mut HashSet<Ty<'tcx>>>,
-}
-
-impl<'cx,'tcx> BoundsChecker<'cx,'tcx> {
-    pub fn new(fcx: &'cx FnCtxt<'cx,'tcx>,
-               scope: ast::NodeId,
-               cache: Option<&'cx mut HashSet<Ty<'tcx>>>)
-               -> BoundsChecker<'cx,'tcx> {
-        let scope = fcx.tcx().region_maps.item_extent(scope);
-        BoundsChecker { fcx: fcx, span: DUMMY_SP, scope: scope,
-                        cache: cache, binding_count: 0 }
-    }
-
-    /// Given a trait ref like `A : Trait<B>`, where `Trait` is defined as (say):
-    ///
-    ///     trait Trait<B:OtherTrait> : Copy { ... }
-    ///
-    /// This routine will check that `B : OtherTrait` and `A : Trait<B>`. It will also recursively
-    /// check that the types `A` and `B` are well-formed.
-    ///
-    /// Note that it does not (currently, at least) check that `A : Copy` (that check is delegated
-    /// to the point where impl `A : Trait<B>` is implemented).
-    pub fn check_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>, span: Span) {
-        let trait_predicates = self.fcx.tcx().lookup_predicates(trait_ref.def_id);
-
-        let bounds = self.fcx.instantiate_bounds(span,
-                                                 trait_ref.substs,
-                                                 &trait_predicates);
-
-        self.fcx.add_obligations_for_parameters(
-            traits::ObligationCause::new(
-                span,
-                self.fcx.body_id,
-                traits::ItemObligation(trait_ref.def_id)),
-            &bounds);
-
-        for &ty in &trait_ref.substs.types {
-            self.check_traits_in_ty(ty, span);
-        }
-    }
-
-    fn check_traits_in_ty(&mut self, ty: Ty<'tcx>, span: Span) {
-        self.span = span;
-        // When checking types outside of a type def'n, we ignore
-        // region obligations. See discussion below in fold_ty().
-        self.binding_count += 1;
-        ty.fold_with(self);
-        self.binding_count -= 1;
-    }
-}
-
-impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'tcx> {
-    fn tcx(&self) -> &ty::ctxt<'tcx> {
-        self.fcx.tcx()
-    }
-
-    fn fold_binder<T>(&mut self, binder: &ty::Binder<T>) -> ty::Binder<T>
-        where T : TypeFoldable<'tcx>
-    {
-        self.binding_count += 1;
-        let value = self.fcx.tcx().liberate_late_bound_regions(
-            self.scope,
-            binder);
-        debug!("BoundsChecker::fold_binder: late-bound regions replaced: {:?} at scope: {:?}",
-               value, self.scope);
-        let value = value.fold_with(self);
-        self.binding_count -= 1;
-        ty::Binder(value)
-    }
-
-    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
-        debug!("BoundsChecker t={:?}",
-               t);
-
-        match self.cache {
-            Some(ref mut cache) => {
-                if !cache.insert(t) {
-                    // Already checked this type! Don't check again.
-                    debug!("cached");
-                    return t;
-                }
-            }
-            None => { }
-        }
-
-        match t.sty{
-            ty::TyStruct(def, substs) |
-            ty::TyEnum(def, substs) => {
-                let type_predicates = def.predicates(self.fcx.tcx());
-                let bounds = self.fcx.instantiate_bounds(self.span, substs,
-                                                         &type_predicates);
-
-                if self.binding_count == 0 {
-                    self.fcx.add_obligations_for_parameters(
-                        traits::ObligationCause::new(self.span,
-                                                     self.fcx.body_id,
-                                                     traits::ItemObligation(def.did)),
-                        &bounds);
-                } else {
-                    // There are two circumstances in which we ignore
-                    // region obligations.
-                    //
-                    // The first is when we are inside of a closure
-                    // type. This is because in that case the region
-                    // obligations for the parameter types are things
-                    // that the closure body gets to assume and the
-                    // caller must prove at the time of call. In other
-                    // words, if there is a type like `<'a, 'b> | &'a
-                    // &'b int |`, it is well-formed, and caller will
-                    // have to show that `'b : 'a` at the time of
-                    // call.
-                    //
-                    // The second is when we are checking for
-                    // well-formedness outside of a type def'n or fn
-                    // body. This is for a similar reason: in general,
-                    // we only do WF checking for regions in the
-                    // result of expressions and type definitions, so
-                    // to as allow for implicit where clauses.
-                    //
-                    // (I believe we should do the same for traits, but
-                    // that will require an RFC. -nmatsakis)
-                    let bounds = filter_to_trait_obligations(bounds);
-                    self.fcx.add_obligations_for_parameters(
-                        traits::ObligationCause::new(self.span,
-                                                     self.fcx.body_id,
-                                                     traits::ItemObligation(def.did)),
-                        &bounds);
-                }
-
-                self.fold_substs(substs);
-            }
-            _ => {
-                super_fold_ty(self, t);
-            }
-        }
-
-        t // we're not folding to produce a new type, so just return `t` here
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// ADT
-
-struct AdtVariant<'tcx> {
-    fields: Vec<AdtField<'tcx>>,
-}
-
-struct AdtField<'tcx> {
-    ty: Ty<'tcx>,
-    span: Span,
-}
-
-fn struct_variant<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                            struct_def: &hir::VariantData)
-                            -> AdtVariant<'tcx> {
-    let fields =
-        struct_def.fields().iter()
-        .map(|field| {
-            let field_ty = fcx.tcx().node_id_to_type(field.node.id);
-            let field_ty = fcx.instantiate_type_scheme(field.span,
-                                                       &fcx.inh
-                                                           .infcx
-                                                           .parameter_environment
-                                                           .free_substs,
-                                                       &field_ty);
-            AdtField { ty: field_ty, span: field.span }
-        })
-        .collect();
-    AdtVariant { fields: fields }
-}
-
-fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                           enum_def: &hir::EnumDef)
-                           -> Vec<AdtVariant<'tcx>> {
-    enum_def.variants.iter()
-        .map(|variant| struct_variant(fcx, &variant.node.data))
-        .collect()
-}
-
-fn filter_to_trait_obligations<'tcx>(bounds: ty::InstantiatedPredicates<'tcx>)
-                                     -> ty::InstantiatedPredicates<'tcx>
-{
-    let mut result = ty::InstantiatedPredicates::empty();
-    for (space, _, predicate) in bounds.predicates.iter_enumerated() {
-        match *predicate {
-            ty::Predicate::Trait(..) |
-            ty::Predicate::Projection(..) => {
-                result.predicates.push(space, predicate.clone())
-            }
-            ty::Predicate::WellFormed(..) |
-            ty::Predicate::ObjectSafe(..) |
-            ty::Predicate::Equate(..) |
-            ty::Predicate::TypeOutlives(..) |
-            ty::Predicate::RegionOutlives(..) => {
-            }
-        }
-    }
-    result
-}
index ffe55c9b29b99140babe46c4b48acb2897805cfb..5d0e713012f2a618d63ca1efd8933d0d588649b9 100644 (file)
@@ -21,7 +21,6 @@
 
 use std::cell::RefCell;
 use std::collections::HashSet;
-use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap::{Span};
 use syntax::parse::token::{special_idents};
@@ -38,8 +37,7 @@ pub fn new(ccx: &'ccx CrateCtxt<'ccx, 'tcx>)
                -> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
         CheckTypeWellFormedVisitor {
             ccx: ccx,
-            code: traits::ObligationCauseCode::RFC1214(
-                Rc::new(traits::ObligationCauseCode::MiscObligation))
+            code: traits::ObligationCauseCode::MiscObligation
         }
     }
 
@@ -311,8 +309,7 @@ fn check_impl(&mut self,
                         ty::wf::trait_obligations(fcx.infcx(),
                                                   fcx.body_id,
                                                   &trait_ref,
-                                                  ast_trait_ref.path.span,
-                                                  true);
+                                                  ast_trait_ref.path.span);
                     for obligation in obligations {
                         fcx.register_predicate(obligation);
                     }
@@ -343,8 +340,7 @@ fn check_where_clauses<'fcx>(&mut self,
                       .flat_map(|p| ty::wf::predicate_obligations(fcx.infcx(),
                                                                   fcx.body_id,
                                                                   p,
-                                                                  span,
-                                                                  true));
+                                                                  span));
 
         for obligation in obligations {
             fcx.register_predicate(obligation);
index 5cbe142ab1992989e3235b1e7f471e6fe0512ada..7d1f71967a2d5a524a8d5bb2b3953726b3bc2087 100644 (file)
@@ -190,7 +190,7 @@ fn visit_item(&mut self, item: &'v hir::Item) {
                     None => { }
                 }
             }
-            hir::ItemImpl(_, _, _, Some(_), ref self_ty, _) => {
+            hir::ItemImpl(_, _, _, Some(_), _, _) => {
                 let impl_def_id = self.tcx.map.local_def_id(item.id);
                 let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap();
                 let trait_def_id = trait_ref.def_id;
@@ -200,16 +200,10 @@ fn visit_item(&mut self, item: &'v hir::Item) {
                         // if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
 
                         if !traits::is_object_safe(self.tcx, data.principal_def_id()) {
-                            // FIXME(#27579). This just means the
-                            // self-ty is illegal; WF will report this
-                            // error. But it will do so as a warning
-                            // for a release or two.  For backwards
-                            // compat reasons, then, we continue to
-                            // report it here so that things which
-                            // were errors remain errors.
-                            span_err!(self.tcx.sess, self_ty.span, E0372,
-                                      "the trait `{}` cannot be made into an object",
-                                      self.tcx.item_path_str(data.principal_def_id()));
+                            // This is an error, but it will be
+                            // reported by wfcheck.  Ignore it
+                            // here. This is tested by
+                            // `coherence-impl-trait-for-trait-object-safe.rs`.
                         } else {
                             let mut supertrait_def_ids =
                                 traits::supertrait_def_ids(self.tcx, data.principal_def_id());
index 9f8368b775bebffcf350a5a9e9fb56a5881a353c..5f2582a548bacc6199f057d655aa4a97a9c5de41 100644 (file)
@@ -3114,14 +3114,6 @@ impl Baz for Bar { } // Note: This is OK
 ```
 "##,
 
-E0372: r##"
-Trying to implement a trait for a trait object (as in `impl Trait1 for
-Trait2 { ... }`) does not work if the trait is not object-safe. Please see the
-[RFC 255] for more details on object safety rules.
-
-[RFC 255]: https://github.com/rust-lang/rfcs/pull/255
-"##,
-
 E0379: r##"
 Trait methods cannot be declared `const` by design. For more information, see
 [RFC 911].
@@ -3486,6 +3478,7 @@ fn main() {
 //  E0319, // trait impls for defaulted traits allowed just for structs/enums
     E0320, // recursive overflow during dropck
     E0328, // cannot implement Unsize explicitly
+//  E0372, // coherence not object safe
     E0374, // the trait `CoerceUnsized` may only be implemented for a coercion
            // between structures with one field being coerced, none found
     E0375, // the trait `CoerceUnsized` may only be implemented for a coercion
index da246eff7da02f192e643d4c90ec2819a7b34e9f..c0ede6370f1b12e56d80c2f5b13dea2bc83a7b82 100644 (file)
@@ -346,8 +346,8 @@ pub fn check_crate(tcx: &ty::ctxt, trait_map: ty::TraitMap) {
           coherence::check_coherence(&ccx));
     });
 
-    time(time_passes, "wf checking (old)", ||
-        check::check_wf_old(&ccx));
+    time(time_passes, "wf checking", ||
+        check::check_wf_new(&ccx));
 
     time(time_passes, "item-types checking", ||
         check::check_item_types(&ccx));
@@ -358,11 +358,6 @@ pub fn check_crate(tcx: &ty::ctxt, trait_map: ty::TraitMap) {
     time(time_passes, "drop-impl checking", ||
         check::check_drop_impls(&ccx));
 
-    // Do this last so that if there are errors in the old code, they
-    // get reported, and we don't get extra warnings.
-    time(time_passes, "wf checking (new)", ||
-        check::check_wf_new(&ccx));
-
     check_for_entry_fn(&ccx);
     tcx.sess.abort_if_errors();
 }
index 318ff410cbad4de25436c030a85b328549181807..3f3913471b8958193c7a2543e408350412d508c9 100644 (file)
@@ -19,6 +19,7 @@
 use iter::Iterator;
 use libc;
 use mem;
+use memchr;
 use ops::Deref;
 use option::Option::{self, Some, None};
 use os::raw::c_char;
@@ -188,7 +189,7 @@ pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, NulError> {
     }
 
     fn _new(bytes: Vec<u8>) -> Result<CString, NulError> {
-        match bytes.iter().position(|x| *x == 0) {
+        match memchr::memchr(0, &bytes) {
             Some(i) => Err(NulError(i, bytes)),
             None => Ok(unsafe { CString::from_vec_unchecked(bytes) }),
         }
index 90a79da34835443e7dbfc03b53f221207a014082..79eedbeda2c727375b9c93bc2aa6d5d80245e550 100644 (file)
@@ -18,6 +18,7 @@
 use error;
 use fmt;
 use io::{self, DEFAULT_BUF_SIZE, Error, ErrorKind, SeekFrom};
+use memchr;
 
 /// The `BufReader` struct adds buffering to any reader.
 ///
@@ -746,7 +747,7 @@ pub fn into_inner(self) -> Result<W, IntoInnerError<LineWriter<W>>> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<W: Write> Write for LineWriter<W> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        match buf.iter().rposition(|b| *b == b'\n') {
+        match memchr::memrchr(b'\n', buf) {
             Some(i) => {
                 let n = try!(self.inner.write(&buf[..i + 1]));
                 if n != i + 1 { return Ok(n) }
index efe40cf07c130981514329179759805502c9a57e..cc3f8097a88e9df5bd0236ab88c152e50113228f 100644 (file)
 use string::String;
 use str;
 use vec::Vec;
+use memchr;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::buffered::{BufReader, BufWriter, LineWriter};
@@ -1194,7 +1195,7 @@ fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
                 Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
                 Err(e) => return Err(e)
             };
-            match available.iter().position(|x| *x == delim) {
+            match memchr::memchr(delim, available) {
                 Some(i) => {
                     buf.extend_from_slice(&available[..i + 1]);
                     (true, i + 1)
index 0f8b2f6e17b257134f04bff2cc4d0a9585f00c02..eba0c799cd2c1c08208c102ce08924bb4dde3795 100644 (file)
 #![feature(link_args)]
 #![feature(linkage)]
 #![feature(macro_reexport)]
+#![feature(num_bits_bytes)]
 #![feature(on_unimplemented)]
 #![feature(oom)]
 #![feature(optin_builtin_traits)]
 pub mod process;
 pub mod sync;
 pub mod time;
+mod memchr;
 
 #[macro_use]
 #[path = "sys/common/mod.rs"] mod sys_common;
diff --git a/src/libstd/memchr.rs b/src/libstd/memchr.rs
new file mode 100644 (file)
index 0000000..c654efd
--- /dev/null
@@ -0,0 +1,386 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+//
+// Original implementation taken from rust-memchr
+// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
+
+
+
+/// A safe interface to `memchr`.
+///
+/// Returns the index corresponding to the first occurrence of `needle` in
+/// `haystack`, or `None` if one is not found.
+///
+/// memchr reduces to super-optimized machine code at around an order of
+/// magnitude faster than `haystack.iter().position(|&b| b == needle)`.
+/// (See benchmarks.)
+///
+/// # Example
+///
+/// This shows how to find the first position of a byte in a byte string.
+///
+/// ```rust,ignore
+/// use memchr::memchr;
+///
+/// let haystack = b"the quick brown fox";
+/// assert_eq!(memchr(b'k', haystack), Some(8));
+/// ```
+pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
+    // libc memchr
+    #[cfg(not(target_os = "windows"))]
+    fn memchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
+        use libc;
+
+        let p = unsafe {
+            libc::memchr(
+                haystack.as_ptr() as *const libc::c_void,
+                needle as libc::c_int,
+                haystack.len() as libc::size_t)
+        };
+        if p.is_null() {
+            None
+        } else {
+            Some(p as usize - (haystack.as_ptr() as usize))
+        }
+    }
+
+    // use fallback on windows, since it's faster
+    #[cfg(target_os = "windows")]
+    fn memchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
+        fallback::memchr(needle, haystack)
+    }
+
+    memchr_specific(needle, haystack)
+}
+
+/// A safe interface to `memrchr`.
+///
+/// Returns the index corresponding to the last occurrence of `needle` in
+/// `haystack`, or `None` if one is not found.
+///
+/// # Example
+///
+/// This shows how to find the last position of a byte in a byte string.
+///
+/// ```rust,ignore
+/// use memchr::memrchr;
+///
+/// let haystack = b"the quick brown fox";
+/// assert_eq!(memrchr(b'o', haystack), Some(17));
+/// ```
+pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
+
+    #[cfg(target_os = "linux")]
+    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
+        use libc;
+
+        // GNU's memrchr() will - unlike memchr() - error if haystack is empty.
+        if haystack.is_empty() {return None}
+        let p = unsafe {
+            libc::memrchr(
+                haystack.as_ptr() as *const libc::c_void,
+                needle as libc::c_int,
+                haystack.len() as libc::size_t)
+        };
+        if p.is_null() {
+            None
+        } else {
+            Some(p as usize - (haystack.as_ptr() as usize))
+        }
+    }
+
+    #[cfg(not(target_os = "linux"))]
+    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
+        haystack.iter().rposition(|&b| b == needle)
+    }
+
+    memrchr_specific(needle, haystack)
+}
+
+#[allow(dead_code)]
+mod fallback {
+    use cmp;
+    use usize;
+
+    const LO_U64: u64 = 0x0101010101010101;
+    const HI_U64: u64 = 0x8080808080808080;
+
+    // use truncation
+    const LO_USIZE: usize = LO_U64 as usize;
+    const HI_USIZE: usize = HI_U64 as usize;
+
+    /// Return `true` if `x` contains any zero byte.
+    ///
+    /// From *Matters Computational*, J. Arndt
+    ///
+    /// "The idea is to subtract one from each of the bytes and then look for
+    /// bytes where the borrow propagated all the way to the most significant
+    /// bit."
+    #[inline]
+    fn contains_zero_byte(x: usize) -> bool {
+        x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0
+    }
+
+    #[cfg(target_pointer_width = "32")]
+    #[inline]
+    fn repeat_byte(b: u8) -> usize {
+        let mut rep = (b as usize) << 8 | b as usize;
+        rep = rep << 16 | rep;
+        rep
+    }
+
+    #[cfg(target_pointer_width = "64")]
+    #[inline]
+    fn repeat_byte(b: u8) -> usize {
+        let mut rep = (b as usize) << 8 | b as usize;
+        rep = rep << 16 | rep;
+        rep = rep << 32 | rep;
+        rep
+    }
+
+    /// Return the first index matching the byte `a` in `text`.
+    pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
+        // Scan for a single byte value by reading two `usize` words at a time.
+        //
+        // Split `text` in three parts
+        // - unaligned inital part, before the first word aligned address in text
+        // - body, scan by 2 words at a time
+        // - the last remaining part, < 2 word size
+        let len = text.len();
+        let ptr = text.as_ptr();
+
+        // search up to an aligned boundary
+        let align = (ptr as usize) & (usize::BYTES- 1);
+        let mut offset;
+        if align > 0 {
+            offset = cmp::min(usize::BYTES - align, len);
+            if let Some(index) = text[..offset].iter().position(|elt| *elt == x) {
+                return Some(index);
+            }
+        } else {
+            offset = 0;
+        }
+
+        // search the body of the text
+        let repeated_x = repeat_byte(x);
+
+        if len >= 2 * usize::BYTES {
+            while offset <= len - 2 * usize::BYTES {
+                unsafe {
+                    let u = *(ptr.offset(offset as isize) as *const usize);
+                    let v = *(ptr.offset((offset + usize::BYTES) as isize) as *const usize);
+
+                    // break if there is a matching byte
+                    let zu = contains_zero_byte(u ^ repeated_x);
+                    let zv = contains_zero_byte(v ^ repeated_x);
+                    if zu || zv {
+                        break;
+                    }
+                }
+                offset += usize::BYTES * 2;
+            }
+        }
+
+        // find the byte after the point the body loop stopped
+        text[offset..].iter().position(|elt| *elt == x).map(|i| offset + i)
+    }
+
+    /// Return the last index matching the byte `a` in `text`.
+    pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
+        // Scan for a single byte value by reading two `usize` words at a time.
+        //
+        // Split `text` in three parts
+        // - unaligned tail, after the last word aligned address in text
+        // - body, scan by 2 words at a time
+        // - the first remaining bytes, < 2 word size
+        let len = text.len();
+        let ptr = text.as_ptr();
+
+        // search to an aligned boundary
+        let end_align = (ptr as usize + len) & (usize::BYTES - 1);
+        let mut offset;
+        if end_align > 0 {
+            offset = len - cmp::min(usize::BYTES - end_align, len);
+            if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) {
+                return Some(offset + index);
+            }
+        } else {
+            offset = len;
+        }
+
+        // search the body of the text
+        let repeated_x = repeat_byte(x);
+
+        while offset >= 2 * usize::BYTES {
+            unsafe {
+                let u = *(ptr.offset(offset as isize - 2 * usize::BYTES as isize) as *const usize);
+                let v = *(ptr.offset(offset as isize - usize::BYTES as isize) as *const usize);
+
+                // break if there is a matching byte
+                let zu = contains_zero_byte(u ^ repeated_x);
+                let zv = contains_zero_byte(v ^ repeated_x);
+                if zu || zv {
+                    break;
+                }
+            }
+            offset -= 2 * usize::BYTES;
+        }
+
+        // find the byte before the point the body loop stopped
+        text[..offset].iter().rposition(|elt| *elt == x)
+    }
+
+    // test fallback implementations on all plattforms
+    #[test]
+    fn matches_one() {
+        assert_eq!(Some(0), memchr(b'a', b"a"));
+    }
+
+    #[test]
+    fn matches_begin() {
+        assert_eq!(Some(0), memchr(b'a', b"aaaa"));
+    }
+
+    #[test]
+    fn matches_end() {
+        assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
+    }
+
+    #[test]
+    fn matches_nul() {
+        assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
+    }
+
+    #[test]
+    fn matches_past_nul() {
+        assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
+    }
+
+    #[test]
+    fn no_match_empty() {
+        assert_eq!(None, memchr(b'a', b""));
+    }
+
+    #[test]
+    fn no_match() {
+        assert_eq!(None, memchr(b'a', b"xyz"));
+    }
+
+    #[test]
+    fn matches_one_reversed() {
+        assert_eq!(Some(0), memrchr(b'a', b"a"));
+    }
+
+    #[test]
+    fn matches_begin_reversed() {
+        assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
+    }
+
+    #[test]
+    fn matches_end_reversed() {
+        assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
+    }
+
+    #[test]
+    fn matches_nul_reversed() {
+        assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
+    }
+
+    #[test]
+    fn matches_past_nul_reversed() {
+        assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
+    }
+
+    #[test]
+    fn no_match_empty_reversed() {
+        assert_eq!(None, memrchr(b'a', b""));
+    }
+
+    #[test]
+    fn no_match_reversed() {
+        assert_eq!(None, memrchr(b'a', b"xyz"));
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    // test the implementations for the current plattform
+    use super::{memchr, memrchr};
+
+    #[test]
+    fn matches_one() {
+        assert_eq!(Some(0), memchr(b'a', b"a"));
+    }
+
+    #[test]
+    fn matches_begin() {
+        assert_eq!(Some(0), memchr(b'a', b"aaaa"));
+    }
+
+    #[test]
+    fn matches_end() {
+        assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
+    }
+
+    #[test]
+    fn matches_nul() {
+        assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
+    }
+
+    #[test]
+    fn matches_past_nul() {
+        assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
+    }
+
+    #[test]
+    fn no_match_empty() {
+        assert_eq!(None, memchr(b'a', b""));
+    }
+
+    #[test]
+    fn no_match() {
+        assert_eq!(None, memchr(b'a', b"xyz"));
+    }
+
+    #[test]
+    fn matches_one_reversed() {
+        assert_eq!(Some(0), memrchr(b'a', b"a"));
+    }
+
+    #[test]
+    fn matches_begin_reversed() {
+        assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
+    }
+
+    #[test]
+    fn matches_end_reversed() {
+        assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
+    }
+
+    #[test]
+    fn matches_nul_reversed() {
+        assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
+    }
+
+    #[test]
+    fn matches_past_nul_reversed() {
+        assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
+    }
+
+    #[test]
+    fn no_match_empty_reversed() {
+        assert_eq!(None, memrchr(b'a', b""));
+    }
+
+    #[test]
+    fn no_match_reversed() {
+        assert_eq!(None, memrchr(b'a', b"xyz"));
+    }
+}
index 91c3819307ffef652e1477421fb8ae60c385a0da..be1fe9b2a9bd7d27344379acf6638be59cbf88b3 100644 (file)
@@ -20,6 +20,7 @@
 use fmt;
 use io::{self, Error, ErrorKind};
 use path;
+use str;
 use sys::pipe::{self, AnonPipe};
 use sys::process as imp;
 use sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
@@ -400,6 +401,32 @@ pub struct Output {
     pub stderr: Vec<u8>,
 }
 
+// If either stderr or stdout are valid utf8 strings it prints the valid
+// strings, otherwise it prints the byte sequence instead
+#[stable(feature = "process_output_debug", since = "1.7.0")]
+impl fmt::Debug for Output {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+
+        let stdout_utf8 = str::from_utf8(&self.stdout);
+        let stdout_debug: &fmt::Debug = match stdout_utf8 {
+            Ok(ref str) => str,
+            Err(_) => &self.stdout
+        };
+
+        let stderr_utf8 = str::from_utf8(&self.stderr);
+        let stderr_debug: &fmt::Debug = match stderr_utf8 {
+            Ok(ref str) => str,
+            Err(_) => &self.stderr
+        };
+
+        fmt.debug_struct("Output")
+            .field("status", &self.status)
+            .field("stdout", stdout_debug)
+            .field("stderr", stderr_debug)
+            .finish()
+    }
+}
+
 /// Describes what to do with a standard I/O stream for a child process.
 #[stable(feature = "process", since = "1.0.0")]
 pub struct Stdio(StdioImp);
index 7a4a0f96b3090caba206ab827eede372d3a830c9..21e60420c186adb48a19058884006bcd763f2455 100644 (file)
@@ -47,6 +47,7 @@
 //!     if the entropy pool is very small, such as immediately after first booting.
 //!     Linux 3.17 added the `getrandom(2)` system call which solves the issue: it blocks if entropy
 //!     pool is not initialized yet, but it does not block once initialized.
+//!     `getrandom(2)` was based on `getentropy(2)`, an existing system call in OpenBSD.
 //!     `OsRng` tries to use `getrandom(2)` if available, and use `/dev/urandom` fallback if not.
 //!     If an application does not have `getrandom` and likely to be run soon after first booting,
 //!     or on a system with very few entropy sources, one should consider using `/dev/random` via
index c4f59d51f5dade8aa9c6218b0ecd2ad0e3f08823..13965ce810ddc1bbd37a1db10975aa75e61dd526 100644 (file)
@@ -13,7 +13,7 @@
 
 pub use self::imp::OsRng;
 
-#[cfg(all(unix, not(target_os = "ios")))]
+#[cfg(all(unix, not(target_os = "ios"), not(target_os = "openbsd")))]
 mod imp {
     use self::OsRngInner::*;
 
@@ -131,6 +131,7 @@ fn is_getrandom_available() -> bool { false }
     /// - Windows: calls `CryptGenRandom`, using the default cryptographic
     ///   service provider with the `PROV_RSA_FULL` type.
     /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
+    /// - OpenBSD: uses the `getentropy(2)` system call.
     ///
     /// This does not block.
     pub struct OsRng {
@@ -178,6 +179,63 @@ fn fill_bytes(&mut self, v: &mut [u8]) {
     }
 }
 
+#[cfg(target_os = "openbsd")]
+mod imp {
+    use io;
+    use mem;
+    use libc::c_long;
+    use sys::os::errno;
+    use rand::Rng;
+
+    /// A random number generator that retrieves randomness straight from
+    /// the operating system. Platform sources:
+    ///
+    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
+    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
+    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
+    ///   service provider with the `PROV_RSA_FULL` type.
+    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
+    /// - OpenBSD: uses the `getentropy(2)` system call.
+    ///
+    /// This does not block.
+    pub struct OsRng {
+        // dummy field to ensure that this struct cannot be constructed outside
+        // of this module
+        _dummy: (),
+    }
+
+    impl OsRng {
+        /// Create a new `OsRng`.
+        pub fn new() -> io::Result<OsRng> {
+            Ok(OsRng { _dummy: () })
+        }
+    }
+
+    impl Rng for OsRng {
+        fn next_u32(&mut self) -> u32 {
+            let mut v = [0; 4];
+            self.fill_bytes(&mut v);
+            unsafe { mem::transmute(v) }
+        }
+        fn next_u64(&mut self) -> u64 {
+            let mut v = [0; 8];
+            self.fill_bytes(&mut v);
+            unsafe { mem::transmute(v) }
+        }
+        fn fill_bytes(&mut self, v: &mut [u8]) {
+            // getentropy(2) permits a maximum buffer size of 256 bytes
+            for s in v.chunks_mut(256) {
+                let ret = unsafe {
+                    libc::syscall(libc::NR_GETENTROPY, s.as_mut_ptr(), s.len())
+                };
+                if ret == -1 {
+                    panic!("unexpected getentropy error: {}", errno());
+                }
+            }
+        }
+    }
+}
+
 #[cfg(target_os = "ios")]
 mod imp {
     #[cfg(stage0)] use prelude::v1::*;
@@ -196,6 +254,7 @@ mod imp {
     /// - Windows: calls `CryptGenRandom`, using the default cryptographic
     ///   service provider with the `PROV_RSA_FULL` type.
     /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
+    /// - OpenBSD: uses the `getentropy(2)` system call.
     ///
     /// This does not block.
     pub struct OsRng {
@@ -261,6 +320,7 @@ mod imp {
     /// - Windows: calls `CryptGenRandom`, using the default cryptographic
     ///   service provider with the `PROV_RSA_FULL` type.
     /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
+    /// - OpenBSD: uses the `getentropy(2)` system call.
     ///
     /// This does not block.
     pub struct OsRng {
index 9ac11b442da39ca5647434fdc5bd3bb3cc5a6cc5..e634c10d8b7dc64aac46b960a8679c11bc3d801e 100644 (file)
@@ -127,11 +127,11 @@ impl Iterator for ReadDir {
 
     fn next(&mut self) -> Option<io::Result<DirEntry>> {
         extern {
-            fn rust_dirent_t_size() -> c_int;
+            fn rust_dirent_t_size() -> libc::size_t;
         }
 
         let mut buf: Vec<u8> = Vec::with_capacity(unsafe {
-            rust_dirent_t_size() as usize
+            rust_dirent_t_size()
         });
         let ptr = buf.as_mut_ptr() as *mut libc::dirent;
 
index c2bf0651cfff455a3250e4683a733180d5d43b71..12b9d6191a05fb5bd483528ba2397d29d11c8c83 100644 (file)
@@ -22,6 +22,7 @@
 use iter;
 use libc::{self, c_int, c_char, c_void};
 use mem;
+use memchr;
 use path::{self, PathBuf};
 use ptr;
 use slice;
@@ -406,7 +407,7 @@ fn parse(input: &[u8]) -> Option<(OsString, OsString)> {
         if input.is_empty() {
             return None;
         }
-        let pos = input[1..].iter().position(|&b| b == b'=').map(|p| p + 1);
+        let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1);
         pos.map(|p| (
             OsStringExt::from_vec(input[..p].to_vec()),
             OsStringExt::from_vec(input[p+1..].to_vec()),
index 4b0ec8578c12ed5a869d15fb3e8472c10cef5ed0..abc44407eff73af5166b0d3a045296f4ebadb323 100644 (file)
@@ -942,6 +942,7 @@ pub enum Expr_ {
     ExprLit(P<Lit>),
     /// A cast (`foo as f64`)
     ExprCast(P<Expr>, P<Ty>),
+    ExprType(P<Expr>, P<Ty>),
     /// An `if` block, with an optional else block
     ///
     /// `if expr { block } else { expr }`
index 0d38411ac93344adfd0ecefbc23e00975c3dcf10..b2989c42a9e9291827ec1ce85810f81770074485 100644 (file)
 
     // Allows `#[deprecated]` attribute
     ("deprecated", "1.6.0", Some(29935), Active),
+
+    // allow using type ascription in expressions
+    ("type_ascription", "1.6.0", Some(23416), Active),
 ];
 // (changing above list without updating src/doc/reference.md makes @cmr sad)
 
@@ -958,6 +961,10 @@ fn visit_expr(&mut self, e: &ast::Expr) {
                                   "box expression syntax is experimental; \
                                    you can call `Box::new` instead.");
             }
+            ast::ExprType(..) => {
+                self.gate_feature("type_ascription", e.span,
+                                  "type ascription is experimental");
+            }
             _ => {}
         }
         visit::walk_expr(self, e);
index cd2210c71b89539c3420f305fccebe6c323f8664..cb467f9016b6f5f6496635b6fd5bcf2a505bb586 100644 (file)
@@ -1203,6 +1203,9 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
             ExprCast(expr, ty) => {
                 ExprCast(folder.fold_expr(expr), folder.fold_ty(ty))
             }
+            ExprType(expr, ty) => {
+                ExprType(folder.fold_expr(expr), folder.fold_ty(ty))
+            }
             ExprAddrOf(m, ohs) => ExprAddrOf(m, folder.fold_expr(ohs)),
             ExprIf(cond, tr, fl) => {
                 ExprIf(folder.fold_expr(cond),
index ebfcf8c5180cf6454ff133d3902c6d4aca29e058..b625277f2a77215f09c542154c625871d85ed199 100644 (file)
@@ -26,7 +26,7 @@
 use ast::{ExprField, ExprTupField, ExprClosure, ExprIf, ExprIfLet, ExprIndex};
 use ast::{ExprLit, ExprLoop, ExprMac, ExprRange};
 use ast::{ExprMethodCall, ExprParen, ExprPath};
-use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
+use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprType, ExprUnary};
 use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl};
 use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, FunctionRetTy};
 use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic};
@@ -2787,6 +2787,11 @@ pub fn parse_assoc_expr_with(&mut self,
                 lhs = self.mk_expr(lhs.span.lo, rhs.span.hi,
                                    ExprCast(lhs, rhs), None);
                 continue
+            } else if op == AssocOp::Colon {
+                let rhs = try!(self.parse_ty());
+                lhs = self.mk_expr(lhs.span.lo, rhs.span.hi,
+                                   ExprType(lhs, rhs), None);
+                continue
             } else if op == AssocOp::DotDot {
                     // If we didn’t have to handle `x..`, it would be pretty easy to generalise
                     // it to the Fixity::None code.
@@ -2809,7 +2814,6 @@ pub fn parse_assoc_expr_with(&mut self,
                     break
             }
 
-
             let rhs = try!(match op.fixity() {
                 Fixity::Right => self.with_res(restrictions, |this|{
                     this.parse_assoc_expr_with(op.precedence(), LhsExpr::NotYetParsed)
@@ -2856,7 +2860,9 @@ pub fn parse_assoc_expr_with(&mut self,
                     let aopexpr = self.mk_assign_op(codemap::respan(cur_op_span, aop), lhs, rhs);
                     self.mk_expr(lhs_span.lo, rhs_span.hi, aopexpr, None)
                 }
-                AssocOp::As | AssocOp::DotDot => self.bug("As or DotDot branch reached")
+                AssocOp::As | AssocOp::Colon | AssocOp::DotDot => {
+                    self.bug("As, Colon or DotDot branch reached")
+                }
             };
 
             if op.fixity() == Fixity::None { break }
index 1f296dc5d59bd6e83153106d57e0423d1cd6e9a5..ff01f0ac67e4118ec20b781b5442aeb3eabef683 100644 (file)
@@ -444,7 +444,7 @@ fn needs_parentheses(expr: &ast::Expr) -> bool {
         ast::ExprAssign(..) | ast::ExprBinary(..) |
         ast::ExprClosure(..) |
         ast::ExprAssignOp(..) | ast::ExprCast(..) |
-        ast::ExprInPlace(..) => true,
+        ast::ExprInPlace(..) | ast::ExprType(..) => true,
         _ => false,
     }
 }
@@ -2035,6 +2035,11 @@ fn print_expr_outer_attr_style(&mut self,
                 try!(self.word_space("as"));
                 try!(self.print_type(&**ty));
             }
+            ast::ExprType(ref expr, ref ty) => {
+                try!(self.print_expr(&**expr));
+                try!(self.word_space(":"));
+                try!(self.print_type(&**ty));
+            }
             ast::ExprIf(ref test, ref blk, ref elseopt) => {
                 try!(self.print_if(&**test, &**blk, elseopt.as_ref().map(|e| &**e)));
             }
index bf3a8def39011bc243c8e7f239e55b72ec80b33a..87ef96d87ff5c627d72cb3578e22af16ce47679e 100644 (file)
@@ -60,7 +60,9 @@ pub enum AssocOp {
     /// `as`
     As,
     /// `..` range
-    DotDot
+    DotDot,
+    /// `:`
+    Colon,
 }
 
 #[derive(Debug, PartialEq, Eq)]
@@ -100,6 +102,7 @@ pub fn from_token(t: &Token) -> Option<AssocOp> {
             Token::AndAnd => Some(LAnd),
             Token::OrOr => Some(LOr),
             Token::DotDot => Some(DotDot),
+            Token::Colon => Some(Colon),
             _ if t.is_keyword(keywords::As) => Some(As),
             _ => None
         }
@@ -134,7 +137,7 @@ pub fn from_ast_binop(op: ast::BinOp_) -> Self {
     pub fn precedence(&self) -> usize {
         use self::AssocOp::*;
         match *self {
-            As => 14,
+            As | Colon => 14,
             Multiply | Divide | Modulus => 13,
             Add | Subtract => 12,
             ShiftLeft | ShiftRight => 11,
@@ -158,7 +161,7 @@ pub fn fixity(&self) -> Fixity {
             Inplace | Assign | AssignOp(_) => Fixity::Right,
             As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd |
             BitXor | BitOr | Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual |
-            LAnd | LOr => Fixity::Left,
+            LAnd | LOr | Colon => Fixity::Left,
             DotDot => Fixity::None
         }
     }
@@ -168,7 +171,7 @@ pub fn is_comparison(&self) -> bool {
         match *self {
             Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => true,
             Inplace | Assign | AssignOp(_) | As | Multiply | Divide | Modulus | Add | Subtract |
-            ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr | DotDot => false
+            ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr | DotDot | Colon => false
         }
     }
 
@@ -178,7 +181,7 @@ pub fn is_assign_like(&self) -> bool {
             Assign | AssignOp(_) | Inplace => true,
             Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | As | Multiply | Divide |
             Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd |
-            LOr | DotDot => false
+            LOr | DotDot | Colon => false
         }
     }
 
@@ -203,8 +206,7 @@ pub fn to_ast_binop(&self) -> Option<ast::BinOp_> {
             BitOr => Some(ast::BiBitOr),
             LAnd => Some(ast::BiAnd),
             LOr => Some(ast::BiOr),
-            Inplace | Assign | AssignOp(_) | As | DotDot => None
+            Inplace | Assign | AssignOp(_) | As | DotDot | Colon => None
         }
     }
-
 }
index 22bf135f4f9779750e136ac6c5e6b8a2d96ad66e..b8dd54790ce51ecb21cad8c15fbcf74e8308b4bb 100644 (file)
@@ -693,7 +693,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
             visitor.visit_expr(subexpression)
         }
         ExprLit(_) => {}
-        ExprCast(ref subexpression, ref typ) => {
+        ExprCast(ref subexpression, ref typ) | ExprType(ref subexpression, ref typ) => {
             visitor.visit_expr(subexpression);
             visitor.visit_ty(typ)
         }
index 072be5712219aac3b4bea6a8d698aaf850449402..e5c6a17c78ba25191f25e50a4375dfd8487fb9b6 100644 (file)
@@ -19,8 +19,8 @@
 use syntax::ext::base;
 use syntax::ext::base::*;
 use syntax::feature_gate;
-use syntax::parse::token::{intern, InternedString};
-use syntax::parse::token;
+use syntax::parse::token::intern;
+use syntax::parse::{self, token};
 use syntax::ptr::P;
 use syntax::ast::AsmDialect;
 
@@ -58,8 +58,17 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         return DummyResult::expr(sp);
     }
 
-    let mut p = cx.new_parser_from_tts(tts);
-    let mut asm = InternedString::new("");
+    // Split the tts before the first colon, to avoid `asm!("x": y)`  being
+    // parsed as `asm!(z)` with `z = "x": y` which is type ascription.
+    let first_colon = tts.iter().position(|tt| {
+        match *tt {
+            ast::TokenTree::Token(_, token::Colon) |
+            ast::TokenTree::Token(_, token::ModSep) => true,
+            _ => false
+        }
+    }).unwrap_or(tts.len());
+    let mut p = cx.new_parser_from_tts(&tts[first_colon..]);
+    let mut asm = token::InternedString::new("");
     let mut asm_str_style = None;
     let mut outputs = Vec::new();
     let mut inputs = Vec::new();
@@ -79,12 +88,22 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                     cx.span_err(sp, "malformed inline assembly");
                     return DummyResult::expr(sp);
                 }
-                let (s, style) = match expr_to_string(cx, panictry!(p.parse_expr()),
+                // Nested parser, stop before the first colon (see above).
+                let mut p2 = cx.new_parser_from_tts(&tts[..first_colon]);
+                let (s, style) = match expr_to_string(cx, panictry!(p2.parse_expr()),
                                                    "inline assembly must be a string literal") {
                     Some((s, st)) => (s, st),
                     // let compilation continue
                     None => return DummyResult::expr(sp),
                 };
+
+                // This is most likely malformed.
+                if p2.token != token::Eof {
+                    let mut extra_tts = panictry!(p2.parse_all_token_trees());
+                    extra_tts.extend(tts[first_colon..].iter().cloned());
+                    p = parse::tts_to_parser(cx.parse_sess, extra_tts, cx.cfg());
+                }
+
                 asm = s;
                 asm_str_style = Some(style);
             }
index 365f67e56162806777a5b3a8e3fb0be916879e4a..d1bf9090944c202c7940785c87e3f36c9dad92a9 100644 (file)
@@ -326,8 +326,8 @@ fn usage(binary: &str) {
     let message = format!("Usage: {} [OPTIONS] [FILTER]", binary);
     println!(r#"{usage}
 
-The FILTER regex is tested against the name of all tests to run, and
-only those tests that match are run.
+The FILTER string is tested against the name of all tests, and only those
+tests whose names contain the filter are run.
 
 By default, all tests are run in parallel. This can be altered with the
 RUST_TEST_THREADS environment variable when running tests (set it to 1).
index af15bda4c3d4a492d45d4dc676d5fdb2fcd669dc..c2168d785b995e0c0fe9284bc0b149367271895c 100644 (file)
@@ -77,7 +77,7 @@ rust_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) {
     return readdir_r(dirp, entry, result);
 }
 
-int
+size_t
 rust_dirent_t_size() {
     return sizeof(struct dirent);
 }
index b3960c2707b4b81c71a928c867837e64396e6518..175e8730cbcd3f8ccbed893ace5b4d98dd8d1641 100644 (file)
@@ -13,7 +13,7 @@
 
 #![crate_type="lib"]
 
-pub trait Bar {
+pub trait Bar: Sized {
     type T;
 
     fn get(x: Option<Self>) -> <Self as Bar>::T;
index e61fb49add5b1e7aa5f53082113d483488178d3c..b8fd59bf7037df002c7fd0131cfa3d51261933cd 100644 (file)
@@ -11,7 +11,7 @@
 #![crate_name="static_methods_crate"]
 #![crate_type = "lib"]
 
-pub trait read {
+pub trait read: Sized {
     fn readMaybe(s: String) -> Option<Self>;
 }
 
index 233532a6085803400c5ae04f9edbf1d70b4f94a9..0b1d6a5b71ad20e0abb8a6bc1809ab559747fcb0 100644 (file)
@@ -25,10 +25,7 @@ trait Get {
 
 trait Other {
     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
-    // (note that we no longer catch the error here, since the
-    //  error below aborts compilation.
-    //  See also associated-types-no-suitable-supertrait-2.rs
-    //  which checks that this error would be caught eventually.)
+    //~^ ERROR the trait `Get` is not implemented for the type `Self`
 }
 
 impl<T:Get> Other for T {
index 037364c7a531c4ff64a64504fe02bfb61ec62e27..3065ecfaa302d3379a35ad350ac16d3301b80c6a 100644 (file)
@@ -13,7 +13,7 @@
 
 use std::sync::mpsc::{channel, Sender};
 
-trait Foo : Sync+'static {
+trait Foo : Sized+Sync+'static {
     fn foo(self, mut chan: Sender<Self>) { }
 }
 
diff --git a/src/test/compile-fail/coerce-expect-unsized-ascribed.rs b/src/test/compile-fail/coerce-expect-unsized-ascribed.rs
new file mode 100644 (file)
index 0000000..ef65927
--- /dev/null
@@ -0,0 +1,42 @@
+// 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.
+
+// A version of coerce-expect-unsized that uses type ascription.
+// Doesn't work so far, but supposed to work eventually
+
+#![feature(box_syntax, type_ascription)]
+
+use std::fmt::Debug;
+
+pub fn main() {
+    let _ = box { [1, 2, 3] }: Box<[i32]>; //~ ERROR mismatched types
+    let _ = box if true { [1, 2, 3] } else { [1, 3, 4] }: Box<[i32]>; //~ ERROR mismatched types
+    let _ = box match true { true => [1, 2, 3], false => [1, 3, 4] }: Box<[i32]>;
+    //~^ ERROR mismatched types
+    let _ = box { |x| (x as u8) }: Box<Fn(i32) -> _>; //~ ERROR mismatched types
+    let _ = box if true { false } else { true }: Box<Debug>; //~ ERROR mismatched types
+    let _ = box match true { true => 'a', false => 'b' }: Box<Debug>; //~ ERROR mismatched types
+
+    let _ = &{ [1, 2, 3] }: &[i32]; //~ ERROR mismatched types
+    let _ = &if true { [1, 2, 3] } else { [1, 3, 4] }: &[i32]; //~ ERROR mismatched types
+    let _ = &match true { true => [1, 2, 3], false => [1, 3, 4] }: &[i32];
+    //~^ ERROR mismatched types
+    let _ = &{ |x| (x as u8) }: &Fn(i32) -> _; //~ ERROR mismatched types
+    let _ = &if true { false } else { true }: &Debug; //~ ERROR mismatched types
+    let _ = &match true { true => 'a', false => 'b' }: &Debug; //~ ERROR mismatched types
+
+    let _ = Box::new([1, 2, 3]): Box<[i32]>; //~ ERROR mismatched types
+    let _ = Box::new(|x| (x as u8)): Box<Fn(i32) -> _>; //~ ERROR mismatched types
+
+    let _ = vec![
+        Box::new(|x| (x as u8)),
+        box |x| (x as i16 as u8),
+    ]: Vec<Box<Fn(i32) -> _>>;
+}
index b08e4bad1e9c9b127dde7d7b43388b5df7fd9b5b..8bb9556fcc075204f010c66cab853259cb3c1b11 100644 (file)
@@ -13,9 +13,7 @@
 
 // If the trait is not object-safe, we give a more tailored message
 // because we're such schnuckels:
-trait NotObjectSafe { fn eq(&self, other: &Self); }
-impl NotObjectSafe for NotObjectSafe {  //~ ERROR E0372
-    fn eq(&self, other: &Self) { panic!(); }
-}
+trait NotObjectSafe { fn eq(&self, other: Self); }
+impl NotObjectSafe for NotObjectSafe { } //~ ERROR E0038
 
 fn main() { }
index 0aefd0ae28845f1474dc87000d06af4886e1e2e5..7d4c618de665c622712d252d60417fade9974ef5 100644 (file)
@@ -21,14 +21,15 @@ trait Foo<X,Y>: Bar<X> {
 
 trait Bar<X> { }
 
-fn vacuous<A>()
+// We don't always check where clauses for sanity, but in this case
+// wfcheck does report an error here:
+fn vacuous<A>() //~ ERROR the trait `Bar<u32>` is not implemented for the type `i32`
     where i32: Foo<u32, A>
 {
-    // vacuous could never be called, because it requires that i32:
-    // Bar<u32>. But the code doesn't check that this could never be
-    // satisfied.
+    // ... the original intention was to check that we don't use that
+    // vacuous where clause (which could never be satisfied) to accept
+    // the following line and then mess up calls elsewhere.
     require::<i32, u32>();
-    //~^ ERROR the trait `Bar<u32>` is not implemented for the type `i32`
 }
 
 fn require<A,B>()
index ea0d880f4a1cc6a04f9da5415257a3a780e97379..1635a8f69a6cd2b481f91adf5c99402dfc6923d8 100644 (file)
@@ -10,7 +10,7 @@
 
 trait FromStructReader<'a> { }
 trait ResponseHook {
-     fn get<'a, T: FromStructReader<'a>>(&'a self);
+     fn get(&self);
 }
 fn foo(res : Box<ResponseHook>) { res.get } //~ ERROR attempted to take value of method
 fn main() {}
index f5d158d64e19fa0a776a78d61568b76431290587..7643310298da3d84c4e001caefc8d7e52422da53 100644 (file)
@@ -13,11 +13,14 @@ trait Node {
 }
 
 trait Graph<N: Node> {
-    fn nodes<'a, I: Iterator<Item=&'a N>>(&'a self) -> I;
+    fn nodes<'a, I: Iterator<Item=&'a N>>(&'a self) -> I
+        where N: 'a;
 }
 
 impl<N: Node> Graph<N> for Vec<N> {
-    fn nodes<'a, I: Iterator<Item=&'a N>>(&self) -> I {
+    fn nodes<'a, I: Iterator<Item=&'a N>>(&self) -> I
+        where N: 'a
+    {
         self.iter() //~ ERROR mismatched types
     }
 }
index 51deb99a4f2cda7747feae6e2df16f83c0f80e9e..c6c1a0fd17781ab1209e1a4923073f294e043ba9 100644 (file)
@@ -12,7 +12,7 @@
 
 trait Str {}
 
-trait Something {
+trait Something: Sized {
     fn yay<T: Debug>(_: Option<Self>, thing: &[T]);
 }
 
index 5f6216a898a0b0351da1eedee6977fc948a58234..7a6d012a3b6054197879a581b577807953ef9e24 100644 (file)
@@ -19,14 +19,12 @@ fn foo<T>(&self, _: &T) {}
 
 #[inline(never)]
 fn foo(b: &Bar) {
+    //~^ ERROR E0038
     b.foo(&0)
-    //~^ ERROR the trait `Foo` is not implemented for the type `Bar`
-    //~| ERROR E0038
-    //~| WARNING E0038
 }
 
 fn main() {
     let mut thing = Thing;
-    let test: &Bar = &mut thing; //~ ERROR E0038
+    let test: &Bar = &mut thing;
     foo(test);
 }
index aae77c90b6bf2980e9820ae9fe0d9e363d3c59c1..322952ffef1e68aeca87fef0b0118e94adea117e 100644 (file)
@@ -19,10 +19,10 @@ fn qiz() {}
 
 struct Bar {
   foos: &'static [&'static (Qiz + 'static)]
+//~^ ERROR E0038
 }
 
 const FOO : Foo = Foo;
 const BAR : Bar = Bar { foos: &[&FOO]};
-//~^ ERROR E0038
 
 fn main() { }
index 041289c2ccdbdb4af3393b0e526e89c61cf3e6f4..aaf27ba527b18fb936fa49db9a246dd4bc4f380e 100644 (file)
@@ -15,13 +15,10 @@ trait From<Src> {
 }
 
 trait To {
-    fn to<Dst>(
-        self //~ error: the trait `core::marker::Sized` is not implemented
+    fn to<Dst>(  //~ ERROR the trait `core::marker::Sized` is not implemented
+        self
     ) -> <Dst as From<Self>>::Result where Dst: From<Self> {
-        From::from( //~ error: the trait `core::marker::Sized` is not implemented
-            //~^ ERROR E0277
-            self
-        )
+        From::from(self)
     }
 }
 
index a38278eae2411f1c92871586e0d33d907f51faab..3f96a9c342283d0678db124b5d7bfe0e4ca200bc 100644 (file)
@@ -38,6 +38,8 @@ impl<'a> Publisher<'a> for MyStruct<'a> {
     fn subscribe(&mut self, t : Box<Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
         // Not obvious, but there is an implicit lifetime here -------^
         //~^^ ERROR cannot infer
+        //~|  ERROR cannot infer
+        //~|  ERROR cannot infer
         //
         // The fact that `Publisher` is using an implicit lifetime is
         // what was causing the debruijn accounting to be off, so
index f768d6c00ecdb1df44ed1d4e34e31db1866ac42b..6ddfa4c8e3e57c5473b070716e04217b652f7e6f 100644 (file)
@@ -17,11 +17,11 @@ trait Foo {
     fn foo(self);
 }
 
-fn foo<'a,'b,T>(x: &'a T, y: &'b T)
+fn foo<'a,'b,T>(x: &'a T, y: &'b T) //~ ERROR type annotations required
     where &'a T : Foo,
           &'b T : Foo
 {
-    x.foo(); //~ ERROR type annotations required
+    x.foo();
     y.foo();
 }
 
index c08cdd72b38258e74645ed96d7fc4a9b1ce3f941..1a9bb4c29f3e0183ad2f0a6a0cf45e5dd44f0214 100644 (file)
@@ -13,5 +13,5 @@ fn main()
 {
     fn bar(x:i32) ->i32 { 3*x };
     let b:Box<Any> = Box::new(bar as fn(_)->_);
-    b.downcast_ref::<fn(_)->_>(); //~ ERROR E0101
+    b.downcast_ref::<fn(_)->_>(); //~ ERROR E0282
 }
index 68f053c357bed341e4f2742b046f5288b3888ad0..4acb1f70d343c459825c7a6422755d9623b3aac4 100644 (file)
@@ -13,6 +13,6 @@ pub trait ToNbt<T> {
 }
 
 impl ToNbt<Self> {} //~ ERROR use of `Self` outside of an impl or trait
-//~^ WARNING the trait `ToNbt` cannot be made into an object
+//~^ ERROR the trait `ToNbt` cannot be made into an object
 
 fn main() {}
index ee8bc7d6e290103ccfd30543c9db1f45e59a389e..130647966f2d126760c07c634889ee17209b80cb 100644 (file)
@@ -18,6 +18,6 @@ struct S {
 }
 
 fn bar(_x: Foo) {}
-//~^ ERROR E0277
+//~^ ERROR E0038
 
 fn main() {}
index 63e5718537cf9166881efafaa66be30ff683b1a0..341736f7ab5ee8c938539b8f48dc2282ac46861b 100644 (file)
@@ -22,16 +22,13 @@ fn bar<T>(&self, t: T)
 }
 
 fn make_bar<T:Bar>(t: &T) -> &Bar {
-    t
         //~^ ERROR E0038
         //~| NOTE method `bar` has generic type parameters
+    t
 }
 
 fn make_bar_explicit<T:Bar>(t: &T) -> &Bar {
     t as &Bar
-        //~^ ERROR E0038
-        //~| NOTE method `bar` has generic type parameters
-        //~| ERROR E0038
 }
 
 fn make_quux<T:Quux>(t: &T) -> &Quux {
index 55b780906355a8f8b1a21f12679ab1f132938cb5..edd31c1f79649fe98c89f8bc6b5e80f61c0a69eb 100644 (file)
@@ -25,29 +25,15 @@ trait Quux {
 }
 
 fn make_bar<T:Bar>(t: &T) -> &Bar {
-    t
-        //~^ ERROR E0038
-        //~| NOTE method `bar` references the `Self` type in its arguments or return type
-}
-
-fn make_bar_explicit<T:Bar>(t: &T) -> &Bar {
-    t as &Bar
         //~^ ERROR E0038
         //~| NOTE method `bar` references the `Self` type in its arguments or return type
-        //~| ERROR E0038
+    loop { }
 }
 
 fn make_baz<T:Baz>(t: &T) -> &Baz {
-    t
         //~^ ERROR E0038
         //~| NOTE method `bar` references the `Self` type in its arguments or return type
-}
-
-fn make_baz_explicit<T:Baz>(t: &T) -> &Baz {
-    t as &Baz
-        //~^ ERROR E0038
-        //~| NOTE method `bar` references the `Self` type in its arguments or return type
-        //~| ERROR E0038
+    t
 }
 
 fn make_quux<T:Quux>(t: &T) -> &Quux {
index 2dc7983d1b561d3f522177862a62ed295ef757d4..dd1d5af3f4a128a6db005b6fab2d17d2724b0bda 100644 (file)
@@ -16,16 +16,8 @@ trait Foo {
 }
 
 fn foo_implicit<T:Foo+'static>(b: Box<T>) -> Box<Foo+'static> {
-    b
-        //~^ ERROR E0038
-        //~| NOTE method `foo` has no receiver
-}
-
-fn foo_explicit<T:Foo+'static>(b: Box<T>) -> Box<Foo+'static> {
-    b as Box<Foo>
-        //~^ ERROR E0038
-        //~| NOTE method `foo` has no receiver
-        //~| ERROR E0038
+    //~^ ERROR E0038
+    loop { }
 }
 
 fn main() {
index 401602bd681a38b5a536e98fd533c8e8c2492c5f..3e1942d5a01884467d5ae54fed17430553dd0351 100644 (file)
@@ -18,16 +18,8 @@ trait Bar
 }
 
 fn make_bar<T:Bar>(t: &T) -> &Bar {
-    t
         //~^ ERROR E0038
-        //~| NOTE the trait cannot require that `Self : Sized`
-}
-
-fn make_bar_explicit<T:Bar>(t: &T) -> &Bar {
-    t as &Bar
-        //~^ ERROR E0038
-        //~| NOTE the trait cannot require that `Self : Sized`
-        //~| ERROR E0038
+    loop { }
 }
 
 fn main() {
index 29b4e4db65c36d11a70a7b04bbceb1e1dc988c11..501d61d20fed124453edb3b2bad2050c71f7d273 100644 (file)
@@ -16,16 +16,9 @@ trait Bar : Sized {
 }
 
 fn make_bar<T:Bar>(t: &T) -> &Bar {
-    t
-        //~^ ERROR E0038
-        //~| NOTE the trait cannot require that `Self : Sized`
-}
-
-fn make_bar_explicit<T:Bar>(t: &T) -> &Bar {
-    t as &Bar
         //~^ ERROR E0038
         //~| NOTE the trait cannot require that `Self : Sized`
-        //~| ERROR E0038
+    t
 }
 
 fn main() {
index ac269a4d896f2566bbe0600366e7590d602a5d62..152c65cb69bf24b7f3a5aa1076ddd411fad4b03a 100644 (file)
@@ -26,10 +26,10 @@ fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
     // oh dear!
     box B(&*v) as Box<X>
         //~^ ERROR the parameter type `T` may not live long enough
-        //~| WARNING the parameter type `T` may not live long enough
-        //~| WARNING the parameter type `T` may not live long enough
         //~| ERROR the parameter type `T` may not live long enough
-        //~| WARNING the parameter type `T` may not live long enough
+        //~| ERROR the parameter type `T` may not live long enough
+        //~| ERROR the parameter type `T` may not live long enough
+        //~| ERROR the parameter type `T` may not live long enough
         //~| ERROR the parameter type `T` may not live long enough
         //~| ERROR the parameter type `T` may not live long enough
 }
diff --git a/src/test/compile-fail/regions-free-region-ordering-callee-4.rs b/src/test/compile-fail/regions-free-region-ordering-callee-4.rs
new file mode 100644 (file)
index 0000000..bd31d1a
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Tests that callees correctly infer an ordering between free regions
+// that appear in their parameter list.  See also
+// regions-free-region-ordering-caller.rs
+
+fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) {
+    //~^ ERROR reference has a longer lifetime than the data it references
+    // Do not infer ordering from closure argument types.
+    let z: Option<&'a &'b usize> = None;
+}
+
+fn main() {}
index 22724081a1bcec374a1fc33a50c5650d198b6cb2..1893395e2b0079e480edad4b4a6c0963e1b3b707 100644 (file)
@@ -30,11 +30,7 @@ fn ordering3<'a, 'b>(x: &'a usize, y: &'b usize) -> &'a &'b usize {
     panic!();
 }
 
-fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) {
-    // Do not infer ordering from closure argument types.
-    let z: Option<&'a &'b usize> = None;
-    //~^ ERROR reference has a longer lifetime than the data it references
-}
+// see regions-free-region-ordering-callee-4.rs
 
 fn ordering5<'a, 'b>(a: &'a usize, b: &'b usize, x: Option<&'a &'b usize>) {
     let z: Option<&'a &'b usize> = None;
index 47985f931dd34fe190cb588e123f6c69d1959a26..fd186d16559162b214001b548fc5b11301c10c82 100644 (file)
@@ -24,16 +24,13 @@ trait Trait2<'a, 'b> {
     type Foo;
 }
 
-fn wf<T>() { }
-
-// As a side-effect of the conservative process above, this argument
-// is not automatically considered well-formed, since for it to be WF,
-// we would need to know that `'y: 'x`, but we do not infer that.
-fn callee<'x, 'y, T>(
-    t: &'x for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
-{
-    wf::<&'x &'y i32>();
+// As a side-effect of the conservative process above, the type of
+// this argument `t` is not automatically considered well-formed,
+// since for it to be WF, we would need to know that `'y: 'x`, but we
+// do not infer that.
+fn callee<'x, 'y, T>(t: &'x for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
     //~^ ERROR reference has a longer lifetime than the data it references
+{
 }
 
 fn main() { }
index e1f1fdaeb341d5bbcb10469de482e124e9d9ebf0..40b715cf3b14d7ac4dfa59c338ed8aaebef32900 100644 (file)
@@ -14,8 +14,7 @@
 trait TheTrait<'t>: 't { }
 
 struct Foo<'a,'b> {
-    x: Box<TheTrait<'a>+'b>
-        //~^ ERROR reference has a longer lifetime
+    x: Box<TheTrait<'a>+'b> //~ ERROR E0478
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/rfc1214-warn-and-error.rs b/src/test/compile-fail/rfc1214-warn-and-error.rs
deleted file mode 100644 (file)
index 50fd3fc..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that an RFC1214 warning from an earlier function (`foo`) does
-// not suppress an error for the same problem (`WantEq<NotEq>`,
-// `NotEq: !Eq`) in a later function (`bar)`. Earlier versions of the
-// warning mechanism had an issue due to caching.
-
-#![allow(dead_code)]
-#![allow(unused_variables)]
-
-struct WantEq<T:Eq> { t: T }
-
-struct NotEq;
-
-trait Trait<T> { }
-
-fn foo() {
-    let x: Box<Trait<WantEq<NotEq>>> = loop { };
-    //~^ WARN E0277
-}
-
-fn bar() {
-    wf::<WantEq<NotEq>>();
-    //~^ ERROR E0277
-}
-
-fn wf<T>() { }
-
-fn main() { }
index beabdcea2bbe9f5beb3571ebeb19eb9e84e07cc9..01910939a80ebd6af13a30eb67a4e1a4646e0438 100644 (file)
@@ -14,7 +14,7 @@ trait Iterator<A> {
     fn next(&mut self) -> Option<A>;
 }
 
-trait IteratorUtil<A>
+trait IteratorUtil<A>: Sized
 {
     fn zip<B, U: Iterator<U>>(self, other: U) -> ZipIterator<Self, U>;
 }
index 73be7cf0dc0325ad55531dd6dfe4b30e26663039..2d4df77f960452a126928ce40ee05fb108324012 100644 (file)
@@ -22,5 +22,4 @@ fn main() {
     //~^ ERROR E0038
     //~| ERROR E0038
     //~| ERROR E0277
-    //~| WARNING E0038
 }
diff --git a/src/test/compile-fail/type-ascription-feature-gate.rs b/src/test/compile-fail/type-ascription-feature-gate.rs
new file mode 100644 (file)
index 0000000..d3c07d6
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Type ascription is feature gated
+
+fn main() {
+    let a = 10: u8; //~ ERROR type ascription is experimental
+}
diff --git a/src/test/compile-fail/type-ascription-precedence.rs b/src/test/compile-fail/type-ascription-precedence.rs
new file mode 100644 (file)
index 0000000..bb7a8bc
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Operator precedence of type ascription
+// Type ascription has very high precedence, the same as operator `as`
+
+#![feature(type_ascription)]
+
+use std::ops::*;
+
+struct S;
+struct Z;
+
+impl Add<Z> for S {
+    type Output = S;
+    fn add(self, _rhs: Z) -> S { panic!() }
+}
+impl Mul<Z> for S {
+    type Output = S;
+    fn mul(self, _rhs: Z) -> S { panic!() }
+}
+impl Neg for S {
+    type Output = Z;
+    fn neg(self) -> Z { panic!() }
+}
+impl Deref for S {
+    type Target = Z;
+    fn deref(&self) -> &Z { panic!() }
+}
+
+fn main() {
+    &S: &S; // OK
+    (&S): &S; // OK
+    &(S: &S); //~ ERROR mismatched types
+
+    *S: Z; // OK
+    (*S): Z; // OK
+    *(S: Z); //~ ERROR mismatched types
+    //~^ ERROR type `Z` cannot be dereferenced
+
+    -S: Z; // OK
+    (-S): Z; // OK
+    -(S: Z); //~ ERROR mismatched types
+    //~^ ERROR cannot apply unary operator `-` to type `Z`
+
+    S + Z: Z; // OK
+    S + (Z: Z); // OK
+    (S + Z): Z; //~ ERROR mismatched types
+
+    S * Z: Z; // OK
+    S * (Z: Z); // OK
+    (S * Z): Z; //~ ERROR mismatched types
+
+    S .. S: S; // OK
+    S .. (S: S); // OK
+    (S .. S): S; //~ ERROR mismatched types
+}
diff --git a/src/test/compile-fail/type-ascription-soundness.rs b/src/test/compile-fail/type-ascription-soundness.rs
new file mode 100644 (file)
index 0000000..2d882e8
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Type ascription doesn't lead to unsoundness
+
+#![feature(type_ascription)]
+
+fn main() {
+    let arr = &[1u8, 2, 3];
+    let ref x = arr: &[u8]; //~ ERROR mismatched types
+    let ref mut x = arr: &[u8]; //~ ERROR mismatched types
+    match arr: &[u8] { //~ ERROR mismatched types
+        ref x => {}
+    }
+    let _len = (arr: &[u8]).len(); //~ ERROR mismatched types
+}
diff --git a/src/test/compile-fail/typeck-default-trait-impl-trait-where-clause-2.rs b/src/test/compile-fail/typeck-default-trait-impl-trait-where-clause-2.rs
new file mode 100644 (file)
index 0000000..ad58ae9
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-tidy-linelength
+
+// Test that when a `..` impl applies, we also check that any
+// supertrait conditions are met.
+
+#![feature(optin_builtin_traits)]
+
+trait NotImplemented { }
+
+trait MyTrait: Sized
+    where Option<Self> : NotImplemented
+{}
+
+impl NotImplemented for i32 {}
+
+impl MyTrait for .. {}
+
+fn bar<T:NotImplemented>() { }
+
+fn test() {
+    bar::<Option<i32>>();
+    //~^ ERROR the trait `NotImplemented` is not implemented for the type `core::option::Option<i32>`
+}
+
+fn main() {
+}
index 8057ca56621c12930278034aee6bc98b119f3821..ff8fbd49574917f78aac78c181fc5032a2aea6e0 100644 (file)
@@ -17,7 +17,7 @@
 
 trait NotImplemented { }
 
-trait MyTrait
+trait MyTrait: Sized
     where Option<Self> : NotImplemented
 {}
 
@@ -26,20 +26,11 @@ impl NotImplemented for i32 {}
 impl MyTrait for .. {}
 
 fn foo<T:MyTrait>() {
-    bar::<Option<T>>()
     //~^ ERROR the trait `NotImplemented` is not implemented for the type `core::option::Option<T>`
-    //
     // This should probably typecheck. This is #20671.
 }
 
 fn bar<T:NotImplemented>() { }
 
-fn test() {
-    bar::<Option<i32>>();
-    //~^ ERROR the trait `NotImplemented` is not implemented for the type `core::option::Option<i32>`
-}
-
 fn main() {
-    foo::<u32>();
-    //~^ ERROR the trait `NotImplemented` is not implemented for the type `core::option::Option<u32>`
 }
index b46cd302ae5ea83ce1b6d2546295c358001aa148..fe61dee23bc2a03d04f63613132160f78766edc3 100644 (file)
@@ -15,13 +15,13 @@ trait Get {
 }
 
 fn get_min_from_max<'min, 'max, G>()
-    where 'max : 'min, &'max G : Get
+    where 'max : 'min, &'max G : Get, G : 'max
 {
     impls_get::<&'min G>(); //~ ERROR mismatched types
 }
 
 fn get_max_from_min<'min, 'max, G>()
-    where 'max : 'min, &'min G : Get
+    where 'max : 'min, &'min G : Get, G : 'min
 {
     impls_get::<&'max G>(); //~ ERROR mismatched types
 }
index c8b7f35b3aa58355940f5201b3f79a2fab0c7f20..946341a1a75bb7d0dae60c4ce7ed6c47a04f5ae5 100644 (file)
@@ -14,8 +14,8 @@
 #![allow(dead_code)]
 
 struct Foo {
-    foo: [[u8]], //~ WARN E0277
+    foo: [[u8]], //~ ERROR E0277
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index 1d271d1530a75823fc7c3da83ab75e8d0eee0473..e3e79fdd940af47cc88842fb0efb45a6b355fe09 100644 (file)
 
 trait ExtraCopy<T:Copy> { }
 
-enum SomeEnum<T,U> //~ WARN E0277
+enum SomeEnum<T,U> //~ ERROR E0277
     where T: ExtraCopy<U>
 {
     SomeVariant(T,U)
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index 769894613c76496dfb318e339ef46e2a9addc342..3ed9e5d9f1eb58123a5551b9bb75a29cbad3dfa7 100644 (file)
@@ -16,9 +16,9 @@
 
 trait ExtraCopy<T:Copy> { }
 
-fn foo<T,U>() where T: ExtraCopy<U> //~ WARN E0277
+fn foo<T,U>() where T: ExtraCopy<U> //~ ERROR E0277
 {
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index 2d7727fff35033c2c98157c381bff06cf90ee414..a319b676eeb880cf660434e616a5e7212ad60638 100644 (file)
@@ -17,8 +17,8 @@ pub trait Foo<'a> {
 }
 
 impl<'a, T> Foo<'a> for T {
-    type Bar = &'a T; //~ WARN E0309
+    type Bar = &'a T; //~ ERROR E0309
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation
+fn main() { }
index 8a612c321570d4253a196955fc9de04be17e46fb..ba31de98e7f95186f7bb54d11fa222ce70f1d945 100644 (file)
@@ -25,9 +25,9 @@ pub trait Foo {
 
 impl<T> Foo for T {
     type Bar = MySet<T>;
-    //~^ WARN the trait `MyHash` is not implemented for the type `T`
+    //~^ ERROR the trait `MyHash` is not implemented for the type `T`
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
 
index 593c9435f6c751dc607575a58e2018a826507442..8e3bca09758139ac179680b3ca2ddfa771ef01eb 100644 (file)
@@ -20,13 +20,13 @@ struct MustBeCopy<T:Copy> {
 
 struct Foo<T> {
     // needs T: 'static
-    x: fn() -> &'static T //~ WARN E0310
+    x: fn() -> &'static T //~ ERROR E0310
 }
 
 struct Bar<T> {
     // needs T: Copy
-    x: fn(&'static T) //~ WARN E0310
+    x: fn(&'static T) //~ ERROR E0310
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index fc3d234aac252d6ae31db99f70c9c46185e30602..c2f66a2a460c5690c72905c93b65771aabb73173 100644 (file)
 trait MustBeCopy<T:Copy> {
 }
 
-fn bar<T,U>() //~ WARN E0277
+fn bar<T,U>() //~ ERROR E0277
     where T: MustBeCopy<U>
 {
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index c697dfd50ad471c3b9add3da74dfd81b82e08878..11535fb9f9e45685a710d2ac452f4ca4481cf19a 100644 (file)
@@ -21,8 +21,8 @@ struct MustBeCopy<T:Copy> {
 
 struct Foo<T> {
     // needs T: 'static
-    x: Object<&'static T> //~ WARN E0310
+    x: Object<&'static T> //~ ERROR E0310
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index 44671be8355336674ed49ef30e406ec064a2bda1..78e12c47e24debc7b8f631ece604c86003d5783d 100644 (file)
@@ -19,9 +19,9 @@ trait ExtraCopy<T:Copy> { }
 struct Foo<T,U>(T,U);
 
 impl<T,U> Foo<T,U> {
-    fn foo(self) where T: ExtraCopy<U> //~ WARN E0277
+    fn foo(self) where T: ExtraCopy<U> //~ ERROR E0277
     {}
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index a0f588c1961d17ec2c9d6315e6b6bb20e6d270ca..7edbb11e245200270033c8db2d6446d0867cfce0 100644 (file)
@@ -18,9 +18,9 @@ trait ExtraCopy<T:Copy> { }
 
 struct Foo<T,U>(T,U);
 
-impl<T,U> Foo<T,U> where T: ExtraCopy<U> //~ WARN E0277
+impl<T,U> Foo<T,U> where T: ExtraCopy<U> //~ ERROR E0277
 {
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index dc0cbeff153a96c66447e498e5c566b7801918ff..c11b2e4c544e1fd524f25affa77fe82a637c2fed 100644 (file)
@@ -19,14 +19,14 @@ trait Trait<T> { }
 
 struct Foo<'a,T> {
     f: &'a fn(T),
-    //~^ WARN E0309
+    //~^ ERROR E0309
 }
 
 struct Bar<'a,T> {
     f: &'a Trait<T>,
-    //~^ WARN E0309
+    //~^ ERROR E0309
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
 
index 43378061e40c0bc5e04f48e8c458847cfdc67692..e263b251aa379eb58bf5f12a21ebd7a1d47bf20b 100644 (file)
 
 trait ExtraCopy<T:Copy> { }
 
-struct SomeStruct<T,U> //~ WARN E0277
+struct SomeStruct<T,U> //~ ERROR E0277
     where T: ExtraCopy<U>
 {
     data: (T,U)
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index 63a532138e3bd84b3464f78fa581c20818f9a5e1..8420edd66a1809dcaa92f1fe5448fe09b43d518b 100644 (file)
@@ -16,9 +16,9 @@
 
 trait ExtraCopy<T:Copy> { }
 
-trait SomeTrait<T> { //~ WARN E0277
+trait SomeTrait<T> { //~ ERROR E0277
     type Type1: ExtraCopy<T>;
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index b3aa4e19c96560a4cb5c830b8a2da609acf1522f..95d9ffdf9d35958782c0ab8ad105aa2dfc6f5021 100644 (file)
@@ -17,8 +17,8 @@
 trait SomeTrait<'a> {
     type Type1;
     type Type2 = &'a Self::Type1;
-    //~^ WARN E0309
+    //~^ ERROR E0309
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index 8c491e04c981dff443772c539de9a0334f06d8a6..902cbe2676b06a5995ccd67137a695831c1ec096 100644 (file)
@@ -19,8 +19,8 @@ struct IsCopy<T:Copy> { x: T }
 trait SomeTrait {
     type Type1;
     type Type2 = IsCopy<Self::Type1>;
-    //~^ WARN E0277
+    //~^ ERROR E0277
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index 147b3ce236d42d1e599e401ac82eb1399c418235..ca15a6ab648630d17c15f2502463fa1c7ec80ae8 100644 (file)
 
 trait ExtraCopy<T:Copy> { }
 
-trait SomeTrait<T,U> //~ WARN E0277
+trait SomeTrait<T,U> //~ ERROR E0277
     where T: ExtraCopy<U>
 {
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index 57c6c1979f87ed0094714a5f672c53964673af87..453aa2428ce5d1ee94dcf0f5236e524a15ea4970 100644 (file)
@@ -19,11 +19,11 @@ struct Bar<T:Eq+?Sized> { value: Box<T> }
 
 trait Foo {
     fn bar(&self, x: &Bar<Self>) {
-        //~^ WARN E0277
+        //~^ ERROR E0277
         //
         // Here, Eq ought to be implemented.
     }
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index 939876403e54db06d2dfb3e96b88f5c605ec59d5..d94708d3e06a557305a48f7e7abe8722ef71c8cf 100644 (file)
@@ -19,12 +19,11 @@ struct Bar<T:Eq+?Sized> { value: Box<T> }
 
 trait Foo {
     fn bar(&self) -> Bar<Self> {
-        //~^ WARN E0277
+        //~^ ERROR E0277
         //
         // Here, Eq ought to be implemented.
         loop { }
     }
 }
 
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index b1c0d71fc5b3b75c784c8fb315c4c266931db5d6..29c85250583c7900c8d90875bc9711b83cc7d674 100644 (file)
@@ -19,11 +19,11 @@ trait Bar<T:Eq+?Sized> { }
 
 trait Foo {
     fn bar<A>(&self) where A: Bar<Self> {
-        //~^ WARN E0277
+        //~^ ERROR E0277
         //
         // Here, Eq ought to be implemented.
     }
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index ff263c85eb371a6bce67ec6b1430c5c786424914..d88e36faeec600578eda6a43a06d068284929b5d 100644 (file)
@@ -18,10 +18,9 @@ struct Bar<T:Eq+?Sized> { value: Box<T> }
 
 trait Foo {
     fn bar(&self, x: &Bar<Self>);
-        //~^ WARN E0277
+        //~^ ERROR E0277
         //
         // Here, Eq ought to be implemented.
 }
 
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index 5c8f3030c2c21b947879a13dde2a9ac53e12459a..c368ff9a4a82dbf3bb99a3c6f49d5a952eae37dc 100644 (file)
@@ -18,10 +18,9 @@ struct Bar<T:Eq+?Sized> { value: Box<T> }
 
 trait Foo {
     fn bar(&self) -> &Bar<Self>;
-        //~^ WARN E0277
+        //~^ ERROR E0277
         //
         // Here, Eq ought to be implemented.
 }
 
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index 51b5475e51fba1df8398509b65f3482983fcb5c9..f59dca93bb90a72e292fdea49289cad5fc8b2671 100644 (file)
@@ -18,10 +18,10 @@ struct Bar<T:Eq+?Sized> { value: Box<T> }
 
 trait Foo {
     fn bar(&self) where Bar<Self>: Copy;
-        //~^ WARN E0277
+        //~^ ERROR E0277
         //
         // Here, Eq ought to be implemented.
 }
 
 #[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index 58ee766dad112fdb40c52ae89e9a03c8ab6cb794..ea8b2fdf3a14766ad28dbb0d09a8fdf3ac49864f 100644 (file)
@@ -16,8 +16,7 @@
 
 trait ExtraCopy<T:Copy> { }
 
-trait SomeTrait<T>: ExtraCopy<T> { //~ WARN E0277
+trait SomeTrait<T>: ExtraCopy<T> { //~ ERROR E0277
 }
 
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
index 8fb71e13f16a28c5b1ebf4dd019e37d9d564d2f9..107b836d160a5669bbb47bed4b4090795e923205 100644 (file)
@@ -22,7 +22,7 @@ fn hi(&self) -> bool {
 
 fn main() {
     for x in Foo {
-        x: 3    //~ ERROR expected one of `!`, `.`, `::`, `;`, `{`, `}`, or an operator, found `:`
+        x: 3    //~ ERROR expected type, found `3`
     }.hi() {
         println!("yo");
     }
index 1560c83bc70baaad8f55d590579796f14886087e..b1cccc51d7bb9acc70bb389e09a4a83047d0c277 100644 (file)
@@ -22,7 +22,7 @@ fn hi(&self) -> bool {
 
 fn main() {
     if Foo {
-        x: 3    //~ ERROR expected one of `!`, `.`, `::`, `;`, `{`, `}`, or an operator, found `:`
+        x: 3    //~ ERROR expected type, found `3`
     }.hi() {
         println!("yo");
     }
index 2052193df91252610ec3def1a3e54e3657e03152..1c52dc48ccd1ac125f4271f00b7810006f806e47 100644 (file)
@@ -22,7 +22,7 @@ fn hi(&self) -> bool {
 
 fn main() {
     while Foo {
-        x: 3    //~ ERROR expected one of `!`, `.`, `::`, `;`, `{`, `}`, or an operator, found `:`
+        x: 3    //~ ERROR expected type, found `3`
     }.hi() {
         println!("yo");
     }
index 86b41284cdf35ad35e79cc658bc4511109c5b07d..b6d84f9d5a24022dd865f999d15fd0899b38ae03 100644 (file)
@@ -15,4 +15,6 @@
 trait Chromosome<X: Chromosome<i32>> {
 }
 
+impl Chromosome<i32> for i32 { }
+
 fn main() { }
index 50bc9e971fbe587ade419de60ad3a7b6cbbdf8af..4ae5c599b43ddeb5e71b4bfc0c819c8a9010db04 100644 (file)
@@ -22,4 +22,12 @@ trait Get<A> {
 
 struct Struct<C:Chromosome> { c: C }
 
+impl Chromosome for i32 { }
+
+impl Get<Struct<i32>> for i32 {
+    fn get(&self) -> Struct<i32> {
+        Struct { c: *self }
+    }
+}
+
 fn main() { }
index 49a0642ce184dd3981a4cebfb08f197c5027adc8..820872ad3fc501b84f6006d43abe9f9e470dd992 100644 (file)
@@ -14,7 +14,9 @@ fn main() {
     println!("{:?}",y);
 }
 
-trait Foo {
+trait Foo
+    where for<'a> &'a Self: Bar
+{
     fn foo<'a>(&'a self) -> <&'a Self as Bar>::Output;
 }
 
diff --git a/src/test/run-pass/issue-26873-multifile.rs b/src/test/run-pass/issue-26873-multifile.rs
new file mode 100644 (file)
index 0000000..aa525ae
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+//
+// ignore-pretty
+
+mod issue_26873_multifile;
+
+fn main() {}
+
diff --git a/src/test/run-pass/issue-26873-onefile.rs b/src/test/run-pass/issue-26873-onefile.rs
new file mode 100644 (file)
index 0000000..a9a04fd
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod A {
+    pub mod B {
+        use super::*;
+
+        pub struct S;
+    }
+
+    pub mod C {
+        use super::*;
+        use super::B::S;
+
+        pub struct T;
+    }
+
+    pub use self::C::T;
+}
+
+use A::*;
+
+fn main() {}
+
index 8ea0804af18bf5499cf3bb4c11df8dbddb3c8c65..e0d2f13ad6899daabf21850561463fc224940094 100644 (file)
@@ -22,7 +22,7 @@ pub fn size_of_val<T>(val: &T) -> usize {
     val.size_of_val()
 }
 
-pub trait TypeInfo {
+pub trait TypeInfo: Sized {
     fn size_of(_lame_type_hint: Option<Self>) -> usize;
     fn size_of_val(&self) -> usize;
 }
diff --git a/src/test/run-pass/issue_26873_multifile/A/B.rs b/src/test/run-pass/issue_26873_multifile/A/B.rs
new file mode 100644 (file)
index 0000000..8917a98
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use super::*;
+
+pub struct S;
+
diff --git a/src/test/run-pass/issue_26873_multifile/A/C.rs b/src/test/run-pass/issue_26873_multifile/A/C.rs
new file mode 100644 (file)
index 0000000..64aaf9c
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use super::*;
+
+use super::B::S;
+
+pub struct T { i: i32 }
+
diff --git a/src/test/run-pass/issue_26873_multifile/A/mod.rs b/src/test/run-pass/issue_26873_multifile/A/mod.rs
new file mode 100644 (file)
index 0000000..a2aeb1c
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub mod B;
+pub mod C;
+
+pub use self::C::T;
+
diff --git a/src/test/run-pass/issue_26873_multifile/mod.rs b/src/test/run-pass/issue_26873_multifile/mod.rs
new file mode 100644 (file)
index 0000000..3643b94
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod A;
+
+use self::A::*;
+
diff --git a/src/test/run-pass/mir_trans_calls.rs b/src/test/run-pass/mir_trans_calls.rs
new file mode 100644 (file)
index 0000000..2335a3c
--- /dev/null
@@ -0,0 +1,100 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(rustc_attrs)]
+
+#[rustc_mir]
+fn test1(a: isize, b: (i32, i32), c: &[i32]) -> (isize, (i32, i32), &[i32]) {
+    // Test passing a number of arguments including a fat pointer.
+    // Also returning via an out pointer
+    fn callee(a: isize, b: (i32, i32), c: &[i32]) -> (isize, (i32, i32), &[i32]) {
+        (a, b, c)
+    }
+    callee(a, b, c)
+}
+
+#[rustc_mir]
+fn test2(a: isize) -> isize {
+    // Test passing a single argument.
+    // Not using out pointer.
+    fn callee(a: isize) -> isize {
+        a
+    }
+    callee(a)
+}
+
+struct Foo;
+impl Foo {
+    fn inherent_method(&self, a: isize) -> isize { a }
+}
+
+#[rustc_mir]
+fn test3(x: &Foo, a: isize) -> isize {
+    // Test calling inherent method
+    x.inherent_method(a)
+}
+
+trait Bar {
+    fn extension_method(&self, a: isize) -> isize { a }
+}
+impl Bar for Foo {}
+
+#[rustc_mir]
+fn test4(x: &Foo, a: isize) -> isize {
+    // Test calling extension method
+    x.extension_method(a)
+}
+
+#[rustc_mir]
+fn test5(x: &Bar, a: isize) -> isize {
+    // Test calling method on trait object
+    x.extension_method(a)
+}
+
+#[rustc_mir]
+fn test6<T: Bar>(x: &T, a: isize) -> isize {
+    // Test calling extension method on generic callee
+    x.extension_method(a)
+}
+
+trait One<T = Self> {
+    fn one() -> T;
+}
+impl One for isize {
+    fn one() -> isize { 1 }
+}
+
+#[rustc_mir]
+fn test7() -> isize {
+    // Test calling trait static method
+    <isize as One>::one()
+}
+
+struct Two;
+impl Two {
+    fn two() -> isize { 2 }
+}
+
+#[rustc_mir]
+fn test8() -> isize {
+    // Test calling impl static method
+    Two::two()
+}
+
+fn main() {
+    assert_eq!(test1(1, (2, 3), &[4, 5, 6]), (1, (2, 3), &[4, 5, 6][..]));
+    assert_eq!(test2(98), 98);
+    assert_eq!(test3(&Foo, 42), 42);
+    assert_eq!(test4(&Foo, 970), 970);
+    assert_eq!(test5(&Foo, 8576), 8576);
+    assert_eq!(test6(&Foo, 12367), 12367);
+    assert_eq!(test7(), 1);
+    assert_eq!(test8(), 2);
+}
index 16236f94655948c0b1c3a62900573685f0bac694..b6815d929678a6bd0c7cd1b73fde3cf26429df1b 100644 (file)
@@ -17,7 +17,7 @@
 
 use std::ops::Deref;
 
-pub trait ToOwned {
+pub trait ToOwned: Sized {
     type Owned: Borrow<Self>;
     fn to_owned(&self) -> Self::Owned;
 }
index d385804da5790c281113b4df2ab4cea01111269e..c339be25f8bb3fb35f2114765709b26ca4db23ed 100644 (file)
@@ -22,7 +22,7 @@ trait UseLife01 {
 }
 
 trait UseLife02 {
-    fn refs<'a, T, H: HasType<&'a T>>(&'a self) -> H;
+    fn refs<'a, T: 'a, H: HasType<&'a T>>(&'a self) -> H;
 }
 
 
@@ -33,7 +33,7 @@ fn dummy(&self, t: T) -> T { panic!() }
 
 
 trait UseLife03<T> {
-    fn refs<'a, H: HasType<&'a T>>(&'a self) -> H;
+    fn refs<'a, H: HasType<&'a T>>(&'a self) -> H where T: 'a;
 }
 
 
@@ -45,7 +45,7 @@ pub fn top_refs_1<'a, H: HasLife<'a>>(_s: &'a ()) -> H {
     unimplemented!()
 }
 
-pub fn top_refs_2<'a, T, H: HasType<&'a T>>(_s: &'a ()) -> H {
+pub fn top_refs_2<'a, T: 'a, H: HasType<&'a T>>(_s: &'a ()) -> H {
     unimplemented!()
 }
 
index 83c2a9ad33926281c369c1729ded5099dc684254..70515a088e2de597ba2589d16806f43c702671c2 100644 (file)
@@ -16,7 +16,7 @@
 
 use std::cmp::PartialOrd;
 
-pub trait NumCast {
+pub trait NumCast: Sized {
     fn from(i: i32) -> Option<Self>;
 }
 
index 14a6a9a0c664ce1fd1c5f61526db25c0ced5e6b3..e21abdae730bcc433c80488a44779fcbd5127bb5 100644 (file)
@@ -10,7 +10,7 @@
 
 // pretty-expanded FIXME #23616
 
-pub trait NumCast {
+pub trait NumCast: Sized {
     fn from(i: i32) -> Option<Self>;
 }
 
index abf8d2baf8732154115bbe5e674c73c4e22bf512..fb56ae82b303ee7fdc3ef20702e93ec89230d8cc 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait NumCast {
+pub trait NumCast: Sized {
     fn from(i: i32) -> Option<Self>;
 }
 
index c6f8a5d4f1d99f98bda8a384088d0f6123528326..bd442629243ee03e8e02a70052f6e719454dfc25 100644 (file)
@@ -10,7 +10,7 @@
 
 // pretty-expanded FIXME #23616
 
-pub trait NumCast {
+pub trait NumCast: Sized {
     fn from(i: i32) -> Option<Self>;
 }
 
index c7e206cb474b86d81d0dbf3f66484972faf09b26..e353be16b45e515e011b7862609277e895a90692 100644 (file)
@@ -17,7 +17,7 @@ pub trait FuzzyEq<Eps> {
     fn fuzzy_eq_eps(&self, other: &Self, epsilon: &Eps) -> bool;
 }
 
-trait Float: FuzzyEq<Self> {
+trait Float: Sized+FuzzyEq<Self> {
     fn two_pi() -> Self;
 }
 
index 7d975da4a2491b204648192c6ab5f1f76b27bf1f..a025be5d651bc1f414b27504cc74c734c8722734 100644 (file)
@@ -12,7 +12,7 @@ trait Foo<T> {
     fn f(&self, x: &T);
 }
 
-trait Bar : Foo<Self> {
+trait Bar : Sized + Foo<Self> {
     fn g(&self);
 }
 
index 3d82ee67925043e03376c4dae4c1043a63150ac8..73bb4bacf64e1b5b0ba18e6874b83db5c6b53c5b 100644 (file)
@@ -13,7 +13,7 @@ pub trait Add<RHS,Result> {
     fn add(&self, rhs: &RHS) -> Result;
 }
 
-trait MyNum : Add<Self,Self> { }
+trait MyNum : Sized + Add<Self,Self> { }
 
 struct MyInt { val: isize }
 
index 6a3639954350fb44743d43d0f2820f444e5be2f9..7d3ebc19e8f833663a12b99db5f71726080e943d 100644 (file)
@@ -17,7 +17,7 @@ trait Add<RHS,Result>: Panda<RHS> {
     fn add(&self, rhs: &RHS) -> Result;
 }
 
-trait MyNum : Add<Self,Self> { }
+trait MyNum : Sized + Add<Self,Self> { }
 
 struct MyInt { val: isize }
 
diff --git a/src/test/run-pass/type-ascription.rs b/src/test/run-pass/type-ascription.rs
new file mode 100644 (file)
index 0000000..bca384c
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Type ascription doesn't lead to unsoundness
+
+#![feature(type_ascription)]
+
+use std::mem;
+
+const C1: u8 = 10: u8;
+const C2: [u8; 1: usize] = [1];
+
+struct S {
+    a: u8
+}
+
+fn main() {
+    assert_eq!(C1.into(): i32, 10);
+    assert_eq!(C2[0], 1);
+
+    let s = S { a: 10: u8 };
+    let arr = &[1u8, 2, 3];
+
+    let mut v = arr.iter().cloned().collect(): Vec<_>;
+    v.push(4);
+    assert_eq!(v, [1, 2, 3, 4]);
+
+    let a = 1: u8;
+    let b = a.into(): u16;
+    assert_eq!(v[a.into(): usize], 2);
+    assert_eq!(mem::size_of_val(&a), 1);
+    assert_eq!(mem::size_of_val(&b), 2);
+    assert_eq!(b, 1: u16);
+
+    let mut v = Vec::new();
+    v: Vec<u8> = vec![1, 2, 3]; // Lvalue type ascription
+    assert_eq!(v, [1u8, 2, 3]);
+}
index 1cce98ae6b7258ed3efa814a353b6ff53125dd35..5b9fa5230d1e0289f1df1aeb24b8562a3811d444 100644 (file)
@@ -67,26 +67,26 @@ fn f7<X: ?Sized+T3>(x: &X) {
 
 trait T4<X> {
     fn dummy(&self) { }
-    fn m1(x: &T4<X>, y: X);
-    fn m2(x: &T5<X>, y: X);
+    fn m1(&self, x: &T4<X>, y: X);
+    fn m2(&self, x: &T5<X>, y: X);
 }
 trait T5<X: ?Sized> {
     fn dummy(&self) { }
     // not an error (for now)
-    fn m1(x: &T4<X>);
-    fn m2(x: &T5<X>);
+    fn m1(&self, x: &T4<X>);
+    fn m2(&self, x: &T5<X>);
 }
 
 trait T6<X: T> {
     fn dummy(&self) { }
-    fn m1(x: &T4<X>);
-    fn m2(x: &T5<X>);
+    fn m1(&self, x: &T4<X>);
+    fn m2(&self, x: &T5<X>);
 }
 trait T7<X: ?Sized+T> {
     fn dummy(&self) { }
     // not an error (for now)
-    fn m1(x: &T4<X>);
-    fn m2(x: &T5<X>);
+    fn m1(&self, x: &T4<X>);
+    fn m2(&self, x: &T5<X>);
 }
 
 // The last field in a struct or variant may be unsized