]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #10164 : brson/rust/configure, r=brson
authorbors <bors@rust-lang.org>
Thu, 31 Oct 2013 04:06:33 +0000 (21:06 -0700)
committerbors <bors@rust-lang.org>
Thu, 31 Oct 2013 04:06:33 +0000 (21:06 -0700)
Rebase of #9990

81 files changed:
mk/stage0.mk
mk/tests.mk
src/compiletest/runtest.rs
src/etc/vim/indent/rust.vim
src/etc/vim/syntax/rust.vim
src/libextra/enum_set.rs
src/libextra/extra.rs
src/librustc/lib/llvm.rs
src/librustc/metadata/common.rs
src/librustc/metadata/encoder.rs
src/librustc/middle/lint.rs
src/librustc/middle/trans/adt.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/reflect.rs
src/librustc/middle/trans/tvec.rs
src/librustc/middle/ty.rs
src/librustc/middle/typeck/check/mod.rs
src/librustuv/rustuv.rs
src/librustuv/uvio.rs
src/libstd/comm.rs
src/libstd/num/int_macros.rs
src/libstd/reflect.rs
src/libstd/repr.rs
src/libstd/rt/borrowck.rs
src/libstd/rt/comm.rs
src/libstd/rt/crate_map.rs
src/libstd/rt/io/signal.rs
src/libstd/rt/kill.rs
src/libstd/rt/mod.rs
src/libstd/rt/task.rs
src/libstd/rt/uv/addrinfo.rs [deleted file]
src/libstd/rt/uv/async.rs [deleted file]
src/libstd/rt/uv/file.rs [deleted file]
src/libstd/rt/uv/idle.rs [deleted file]
src/libstd/rt/uv/mod.rs [deleted file]
src/libstd/rt/uv/net.rs [deleted file]
src/libstd/rt/uv/pipe.rs [deleted file]
src/libstd/rt/uv/process.rs [deleted file]
src/libstd/rt/uv/signal.rs [deleted file]
src/libstd/rt/uv/timer.rs [deleted file]
src/libstd/rt/uv/tty.rs [deleted file]
src/libstd/rt/uv/uvio.rs [deleted file]
src/libstd/rt/uv/uvll.rs [deleted file]
src/libstd/std.rs
src/libstd/sys.rs
src/libstd/task/mod.rs
src/libstd/task/spawn.rs
src/libstd/unstable/intrinsics.rs
src/libstd/unstable/lang.rs
src/libstd/unstable/raw.rs
src/libsyntax/attr.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/expand.rs
src/rt/rust_upcall.cpp
src/rt/rustrt.def.in
src/rt/sync/rust_thread.cpp
src/rt/sync/rust_thread.h
src/rt/util/array_list.h [deleted file]
src/snapshots.txt
src/test/bench/shootout-binarytrees.rs
src/test/compile-fail/bad-expr-lhs.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-assign-to-constants.rs
src/test/compile-fail/enum-discrim-too-small.rs [new file with mode: 0644]
src/test/compile-fail/fail-expr.rs [deleted file]
src/test/compile-fail/fail-type-err.rs [deleted file]
src/test/compile-fail/lint-ctypes-enum.rs [new file with mode: 0644]
src/test/compile-fail/tag-variant-disr-dup.rs
src/test/debug-info/method-on-enum.rs
src/test/run-fail/fail-macro-send_str.rs [deleted file]
src/test/run-pass/enum-discrim-autosizing.rs [new file with mode: 0644]
src/test/run-pass/enum-discrim-manual-sizing.rs [new file with mode: 0644]
src/test/run-pass/enum-discrim-width-stuff.rs
src/test/run-pass/issue-2718.rs
src/test/run-pass/reflect-visit-data.rs
src/test/run-pass/reflect-visit-type.rs
src/test/run-pass/small-enum-range-edge.rs [new file with mode: 0644]
src/test/run-pass/small-enums-with-fields.rs [new file with mode: 0644]
src/test/run-pass/unit-like-struct-drop-run.rs
src/test/run-pass/zero-size-type-destructors.rs [new file with mode: 0644]

index ad5b9b8a56b5a669de07b0919fada3675214e1b8..3a678cc04f1d99c7af8639d64f9baddc217cc8cc 100644 (file)
@@ -98,17 +98,13 @@ $$(HLIB0_H_$(1))/$(CFG_EXTRALIB_$(1)): \
        $$(Q)cp $$(TLIB$(2)_T_$(1)_H_$(3))/$(EXTRALIB_GLOB_$(1)) $$@
        $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_GLOB_$(4)),$$(notdir $$@))
 
-$$(HLIB0_H_$(1))/$(CFG_LIBRUSTUV_$(1)):
-       touch $$@
-# NOTE: this should get uncommented after a snapshot and the rule above this can
-#      get deleted, right now we're not expecting a librustuv in a snapshot.
-# $$(HLIB0_H_$(1))/$(CFG_LIBRUSTUV_$(1)): \
-#              $$(TLIB$(2)_T_$(1)_H_$(3))/$(CFG_LIBRUSTUV_$(1)) \
-#              | $(HLIB0_H_$(1))/
-#      @$$(call E, cp: $$@)
-#      $$(call CHECK_FOR_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_GLOB_$(4)),$$(notdir $$@))
-#      $$(Q)cp $$(TLIB$(2)_T_$(1)_H_$(3))/$(LIBRUSTUV_GLOB_$(1)) $$@
-#      $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_GLOB_$(4)),$$(notdir $$@))
+$$(HLIB0_H_$(1))/$(CFG_LIBRUSTUV_$(1)): \
+               $$(TLIB$(2)_T_$(1)_H_$(3))/$(CFG_LIBRUSTUV_$(1)) \
+               | $(HLIB0_H_$(1))/
+       @$$(call E, cp: $$@)
+       $$(call CHECK_FOR_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_GLOB_$(4)),$$(notdir $$@))
+       $$(Q)cp $$(TLIB$(2)_T_$(1)_H_$(3))/$(LIBRUSTUV_GLOB_$(1)) $$@
+       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_GLOB_$(4)),$$(notdir $$@))
 
 $$(HLIB0_H_$(1))/$(CFG_LIBRUSTC_$(1)): \
                $$(TLIB$(2)_T_$(1)_H_$(3))/$(CFG_LIBRUSTC_$(1)) \
index 9ef3e8d65cdf39cc19a48fac9b134204e954535e..d228307764f0e5bffcef7ea485b5753efc971dda 100644 (file)
@@ -465,6 +465,17 @@ $(foreach host,$(CFG_HOST), \
       $(eval $(call DEF_TEST_CRATE_RULES,$(stage),$(target),$(host),$(crate))) \
      ))))))
 
+# FIXME (#10104): Raise the stack size to work around rustpkg bypassing
+# the code in rustc that would take care of it.
+define DEF_RUSTPKG_STACK_FIX
+$$(call TEST_OK_FILE,$(1),$(2),$(3),rustpkg): export RUST_MIN_STACK=8000000
+endef
+
+$(foreach host,$(CFG_HOST_TRIPLES), \
+ $(foreach target,$(CFG_TARGET_TRIPLES), \
+  $(foreach stage,$(STAGES), \
+   $(eval $(call DEF_RUSTPKG_STACK_FIX,$(stage),$(target),$(host))))))
+
 
 ######################################################################
 # Rules for the compiletest tests (rpass, rfail, etc.)
index e7e1b11028923c6cc9c057df87e7e198bbc55c60..13c4c7948b803c9a69f64ab914a88836fd3981b7 100644 (file)
@@ -281,7 +281,7 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {
     };
     let config = &mut config;
     let cmds = props.debugger_cmds.connect("\n");
-    let check_lines = props.check_lines.clone();
+    let check_lines = &props.check_lines;
 
     // compile test file (it shoud have 'compile-flags:-g' in the header)
     let mut ProcRes = compile_test(config, props, testfile);
@@ -315,11 +315,34 @@ fn debugger() -> ~str { ~"gdb" }
 
     let num_check_lines = check_lines.len();
     if num_check_lines > 0 {
+        // Allow check lines to leave parts unspecified (e.g., uninitialized
+        // bits in the wrong case of an enum) with the notation "[...]".
+        let check_fragments: ~[~[&str]] = check_lines.map(|s| s.split_str_iter("[...]").collect());
         // check if each line in props.check_lines appears in the
         // output (in order)
         let mut i = 0u;
         for line in ProcRes.stdout.line_iter() {
-            if check_lines[i].trim() == line.trim() {
+            let mut rest = line.trim();
+            let mut first = true;
+            let mut failed = false;
+            for &frag in check_fragments[i].iter() {
+                let found = if first {
+                    if rest.starts_with(frag) { Some(0) } else { None }
+                } else {
+                    rest.find_str(frag)
+                };
+                match found {
+                    None => {
+                        failed = true;
+                        break;
+                    }
+                    Some(i) => {
+                        rest = rest.slice_from(i + frag.len());
+                    }
+                }
+                first = false;
+            }
+            if !failed && rest.len() == 0 {
                 i += 1u;
             }
             if i == num_check_lines {
index ae3ca403aedd8b0f0a5736c386debe876b3c5fee..1f08c5190214f68c711c561800b15384de4d0ef0 100644 (file)
@@ -1,7 +1,7 @@
 " Vim indent file
 " Language:         Rust
 " Author:           Chris Morgan <me@chrismorgan.info>
-" Last Change:      2013 Jul 10
+" Last Change:      2013 Oct 29
 
 " Only load this indent file when no other was loaded.
 if exists("b:did_indent")
@@ -104,8 +104,23 @@ function GetRustIndent(lnum)
        let prevline = s:get_line_trimmed(prevnonblank(a:lnum - 1))
        if prevline[len(prevline) - 1] == ","
                                \ && s:get_line_trimmed(a:lnum) !~ "^\\s*[\\[\\]{}]"
+                               \ && prevline !~ "^\\s*fn\\s"
                " Oh ho! The previous line ended in a comma! I bet cindent will try to
-               " take this too far... For now, let's use the previous line's indent
+               " take this too far... For now, let's normally use the previous line's
+               " indent.
+
+               " One case where this doesn't work out is where *this* line contains
+               " square or curly brackets; then we normally *do* want to be indenting
+               " further.
+               "
+               " Another case where we don't want to is one like a function
+               " definition with arguments spread over multiple lines:
+               "
+               " fn foo(baz: Baz,
+               "        baz: Baz) // <-- cindent gets this right by itself
+               "
+               " There are probably other cases where we don't want to do this as
+               " well. Add them as needed.
                return GetRustIndent(a:lnum - 1)
        endif
 
index e276313201f825ee874fafaf5c5008f0608dea2d..a0a239284ceb716c04e5609cbdcf9aa15039c99d 100644 (file)
@@ -3,7 +3,7 @@
 " Maintainer:   Patrick Walton <pcwalton@mozilla.com>
 " Maintainer:   Ben Blum <bblum@cs.cmu.edu>
 " Maintainer:   Chris Morgan <me@chrismorgan.info>
-" Last Change:  2013 Oct 19
+" Last Change:  2013 Oct 29
 
 if version < 600
   syntax clear
@@ -64,47 +64,45 @@ syn keyword   rustEnumVariant Ok Err
 "syn keyword rustFunction from_str
 
 " Types and traits {{{3
+syn keyword rustTrait Any AnyOwnExt AnyRefExt AnyMutRefExt
+syn keyword rustTrait Ascii AsciiCast OwnedAsciiCast AsciiStr ToBytesConsume
+syn keyword rustTrait Bool
 syn keyword rustTrait ToCStr
+syn keyword rustTrait Char
 syn keyword rustTrait Clone DeepClone
 syn keyword rustTrait Eq ApproxEq Ord TotalEq TotalOrd Ordering Equiv
 syn keyword rustEnumVariant Less Equal Greater
-syn keyword rustTrait Char
 syn keyword rustTrait Container Mutable Map MutableMap Set MutableSet
+syn keyword rustTrait Default
 syn keyword rustTrait Hash
-syn keyword rustTrait Times
+syn keyword rustTrait FromStr
 syn keyword rustTrait FromIterator Extendable
 syn keyword rustTrait Iterator DoubleEndedIterator RandomAccessIterator ClonableIterator
 syn keyword rustTrait OrdIterator MutableDoubleEndedIterator ExactSize
-syn keyword rustTrait Num NumCast CheckedAdd CheckedSub CheckedMul
-syn keyword rustTrait Orderable Signed Unsigned Round
+syn keyword rustTrait Times
+
 syn keyword rustTrait Algebraic Trigonometric Exponential Hyperbolic
-syn keyword rustTrait Integer Fractional Real RealExt
 syn keyword rustTrait Bitwise BitCount Bounded
+syn keyword rustTrait Integer Fractional Real RealExt
+syn keyword rustTrait Num NumCast CheckedAdd CheckedSub CheckedMul
+syn keyword rustTrait Orderable Signed Unsigned Round
 syn keyword rustTrait Primitive Int Float ToStrRadix ToPrimitive FromPrimitive
-syn keyword rustTrait GenericPath
-syn keyword rustTrait Path
-syn keyword rustTrait PosixPath
-syn keyword rustTrait WindowsPath
+syn keyword rustTrait GenericPath Path PosixPath WindowsPath
 syn keyword rustTrait RawPtr
-syn keyword rustTrait Ascii AsciiCast OwnedAsciiCast AsciiStr ToBytesConsume
 syn keyword rustTrait SendStr SendStrOwned SendStrStatic IntoSendStr
 syn keyword rustTrait Str StrVector StrSlice OwnedStr
-syn keyword rustTrait FromStr
 syn keyword rustTrait IterBytes
 syn keyword rustTrait ToStr ToStrConsume
 syn keyword rustTrait CopyableTuple ImmutableTuple
-syn keyword rustTrait Tuple1 ImmutableTuple1
-syn keyword rustTrait Tuple2 Tuple3 Tuple4 Tuple5
-syn keyword rustTrait Tuple6 Tuple7 Tuple8 Tuple9
-syn keyword rustTrait Tuple10 Tuple11 Tuple12
-syn keyword rustTrait ImmutableTuple2 ImmutableTuple3 ImmutableTuple4 ImmutableTuple5
-syn keyword rustTrait ImmutableTuple6 ImmutableTuple7 ImmutableTuple8 ImmutableTuple9
-syn keyword rustTrait ImmutableTuple10 ImmutableTuple11 ImmutableTuple12
-syn keyword rustTrait Vector VectorVector CopyableVector ImmutableVector
+syn keyword rustTrait Tuple1 Tuple2 Tuple3 Tuple4
+syn keyword rustTrait Tuple5 Tuple6 Tuple7 Tuple8
+syn keyword rustTrait Tuple9 Tuple10 Tuple11 Tuple12
+syn keyword rustTrait ImmutableTuple1 ImmutableTuple2 ImmutableTuple3 ImmutableTuple4
+syn keyword rustTrait ImmutableTuple5 ImmutableTuple6 ImmutableTuple7 ImmutableTuple8
+syn keyword rustTrait ImmutableTuple9 ImmutableTuple10 ImmutableTuple11 ImmutableTuple12
 syn keyword rustTrait ImmutableEqVector ImmutableTotalOrdVector ImmutableCopyableVector
 syn keyword rustTrait OwnedVector OwnedCopyableVector OwnedEqVector MutableVector
-syn keyword rustTrait Reader ReaderUtil Writer WriterUtil
-syn keyword rustTrait Default
+syn keyword rustTrait Vector VectorVector CopyableVector ImmutableVector
 
 "syn keyword rustFunction stream
 syn keyword rustTrait Port Chan GenericChan GenericSmartChan GenericPort Peekable
index da9e0a225ba1b47f9b35410912274b9db328e474..75611f88b6384eefe5cea9885a5fec5393b2eb8a 100644 (file)
@@ -140,6 +140,7 @@ mod test {
     use enum_set::*;
 
     #[deriving(Eq)]
+    #[repr(uint)]
     enum Foo {
         A, B, C
     }
index 90434cf0d4912ad0569ecb6d10c890d89d6801eb..c6fc41e683161ed64d4ef3e0d286cbd16709c7e2 100644 (file)
@@ -118,6 +118,8 @@ pub mod extra {
     pub use std::clone;
     pub use std::condition;
     pub use std::cmp;
+    // NOTE: Remove import after next snapshot
+    #[cfg(stage0)]
     pub use std::sys;
     pub use std::unstable;
     pub use std::str;
index 64c6678ec5f726490511b211ddb24b9c00546475..4eb8a0b8fa644c6d924082fab3ce4b1f621064be 100644 (file)
@@ -147,6 +147,7 @@ pub enum RealPredicate {
 pub static Metadata: TypeKind  = 14;
 pub static X86_MMX: TypeKind   = 15;
 
+#[repr(C)]
 pub enum AtomicBinOp {
     Xchg = 0,
     Add  = 1,
@@ -161,6 +162,7 @@ pub enum AtomicBinOp {
     UMin = 10,
 }
 
+#[repr(C)]
 pub enum AtomicOrdering {
     NotAtomic = 0,
     Unordered = 1,
@@ -173,6 +175,7 @@ pub enum AtomicOrdering {
 }
 
 // Consts for the LLVMCodeGenFileType type (in include/llvm/c/TargetMachine.h)
+#[repr(C)]
 pub enum FileType {
     AssemblyFile = 0,
     ObjectFile = 1
@@ -194,6 +197,7 @@ pub enum AsmDialect {
 }
 
 #[deriving(Eq)]
+#[repr(C)]
 pub enum CodeGenOptLevel {
     CodeGenLevelNone = 0,
     CodeGenLevelLess = 1,
@@ -201,6 +205,7 @@ pub enum CodeGenOptLevel {
     CodeGenLevelAggressive = 3,
 }
 
+#[repr(C)]
 pub enum RelocMode {
     RelocDefault = 0,
     RelocStatic = 1,
@@ -208,6 +213,7 @@ pub enum RelocMode {
     RelocDynamicNoPic = 3,
 }
 
+#[repr(C)]
 pub enum CodeGenModel {
     CodeModelDefault = 0,
     CodeModelJITDefault = 1,
index c3bc3e0fe25c1e7ffba2f6fcdd61877f2cf7bda9..6294b6cb6e3128f6cfa400187cb1f8161266c6d4 100644 (file)
@@ -112,6 +112,7 @@ impl items contain tag_item_impl_method elements, and classes
 
 // used to encode crate_ctxt side tables
 #[deriving(Eq)]
+#[repr(uint)]
 pub enum astencode_tag { // Reserves 0x50 -- 0x6f
     tag_ast = 0x50,
 
@@ -143,7 +144,7 @@ impl astencode_tag {
     pub fn from_uint(value : uint) -> Option<astencode_tag> {
         let is_a_tag = first_astencode_tag <= value && value <= last_astencode_tag;
         if !is_a_tag { None } else {
-            Some(unsafe { cast::transmute(value as int) })
+            Some(unsafe { cast::transmute(value) })
         }
     }
 }
index ade5bfe85e4bc1c80551096c80171d18c5d49747..86c4ca0158f19c8d25a8f888acced425a8a698c8 100644 (file)
@@ -989,6 +989,7 @@ fn add_to_index(item: @item, ebml_w: &writer::Encoder,
         encode_family(ebml_w, 't');
         encode_bounds_and_type(ebml_w, ecx, &lookup_item_type(tcx, def_id));
         encode_name(ecx, ebml_w, item.ident);
+        encode_attributes(ebml_w, item.attrs);
         for v in (*enum_definition).variants.iter() {
             encode_variant_id(ebml_w, local_def(v.node.id));
         }
index 1ac14dfc4b1e5d35fa425fa88f13491146c1c2d0..e8f9dad65851beab32e35424518e4cedc13c323d 100644 (file)
@@ -34,6 +34,7 @@
 //! Context itself, span_lint should be used instead of add_lint.
 
 use driver::session;
+use middle::trans::adt; // for `adt::is_ffi_safe`
 use middle::ty;
 use middle::pat_util;
 use metadata::csearch;
@@ -627,6 +628,14 @@ fn check_ty(cx: &Context, ty: &ast::Ty) {
                                 "found rust type `uint` in foreign module, while \
                                 libc::c_uint or libc::c_ulong should be used");
                     }
+                    ast::DefTy(def_id) => {
+                        if !adt::is_ffi_safe(cx.tcx, def_id) {
+                            cx.span_lint(ctypes, ty.span,
+                                         "found enum type without foreign-function-safe \
+                                          representation annotation in foreign module");
+                            // NOTE this message could be more helpful
+                        }
+                    }
                     _ => ()
                 }
             }
index 5e64dc5c2e26e4d98f23642a6702c53210db1c60..997bcbca9ce0b33b245b81d70f00589ae8c331a8 100644 (file)
@@ -14,7 +14,8 @@
  * This module determines how to represent enums, structs, and tuples
  * based on their monomorphized types; it is responsible both for
  * choosing a representation and translating basic operations on
- * values of those types.
+ * values of those types.  (Note: exporting the representations for
+ * debuggers is handled in debuginfo.rs, not here.)
  *
  * Note that the interface treats everything as a general case of an
  * enum, so structs/tuples/etc. have one pseudo-variant with
@@ -29,8 +30,6 @@
  *   that might contain one and adjust GEP indices accordingly.  See
  *   issue #4578.
  *
- * - Using smaller integer types for discriminants.
- *
  * - Store nested enums' discriminants in the same word.  Rather, if
  *   some variants start with enums, and those enums representations
  *   have unused alignment padding between discriminant and body, the
 use middle::trans::type_of;
 use middle::ty;
 use middle::ty::Disr;
+use syntax::abi::{X86, X86_64, Arm, Mips};
 use syntax::ast;
+use syntax::attr;
+use syntax::attr::IntType;
 use util::ppaux::ty_to_str;
 
 use middle::trans::type_::Type;
 
+type Hint = attr::ReprAttr;
+
 
 /// Representations.
 pub enum Repr {
     /// C-like enums; basically an int.
-    CEnum(Disr, Disr), // discriminant range
+    CEnum(IntType, Disr, Disr), // discriminant range (signedness based on the IntType)
     /**
      * Single-case variants, and structs/tuples/records.
      *
@@ -78,7 +82,7 @@ pub enum Repr {
      * General-case enums: for each case there is a struct, and they
      * all start with a field for the discriminant.
      */
-    General(~[Struct]),
+    General(IntType, ~[Struct]),
     /**
      * Two cases distinguished by a nullable pointer: the case with discriminant
      * `nndiscr` is represented by the struct `nonnull`, where the `ptrfield`th
@@ -141,38 +145,26 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr {
             return Univariant(mk_struct(cx, ftys, packed), dtor)
         }
         ty::ty_enum(def_id, ref substs) => {
-            struct Case { discr: Disr, tys: ~[ty::t] };
-            impl Case {
-                fn is_zerolen(&self, cx: &mut CrateContext) -> bool {
-                    mk_struct(cx, self.tys, false).size == 0
-                }
-                fn find_ptr(&self) -> Option<uint> {
-                    self.tys.iter().position(|&ty| mono_data_classify(ty) == MonoNonNull)
-                }
-            }
-
-            let cases = do ty::enum_variants(cx.tcx, def_id).map |vi| {
-                let arg_tys = do vi.args.map |&raw_ty| {
-                    ty::subst(cx.tcx, substs, raw_ty)
-                };
-                Case { discr: vi.disr_val, tys: arg_tys }
-            };
+            let cases = get_cases(cx.tcx, def_id, substs);
+            let hint = ty::lookup_repr_hint(cx.tcx, def_id);
 
             if cases.len() == 0 {
                 // Uninhabitable; represent as unit
+                // (Typechecking will reject discriminant-sizing attrs.)
+                assert_eq!(hint, attr::ReprAny);
                 return Univariant(mk_struct(cx, [], false), false);
             }
 
             if cases.iter().all(|c| c.tys.len() == 0) {
                 // All bodies empty -> intlike
                 let discrs = cases.map(|c| c.discr);
-                return CEnum(*discrs.iter().min().unwrap(), *discrs.iter().max().unwrap());
-            }
-
-            if cases.len() == 1 {
-                // Equivalent to a struct/tuple/newtype.
-                assert_eq!(cases[0].discr, 0);
-                return Univariant(mk_struct(cx, cases[0].tys, false), false)
+                let bounds = IntBounds {
+                    ulo: *discrs.iter().min().unwrap(),
+                    uhi: *discrs.iter().max().unwrap(),
+                    slo: discrs.iter().map(|n| *n as i64).min().unwrap(),
+                    shi: discrs.iter().map(|n| *n as i64).max().unwrap()
+                };
+                return mk_cenum(cx, hint, &bounds);
             }
 
             // Since there's at least one
@@ -184,7 +176,15 @@ fn find_ptr(&self) -> Option<uint> {
                                  ty::item_path_str(cx.tcx, def_id)))
             }
 
-            if cases.len() == 2 {
+            if cases.len() == 1 {
+                // Equivalent to a struct/tuple/newtype.
+                // (Typechecking will reject discriminant-sizing attrs.)
+                assert_eq!(hint, attr::ReprAny);
+                return Univariant(mk_struct(cx, cases[0].tys, false), false)
+            }
+
+            if cases.len() == 2 && hint == attr::ReprAny {
+                // Nullable pointer optimization
                 let mut discr = 0;
                 while discr < 2 {
                     if cases[1 - discr].is_zerolen(cx) {
@@ -207,13 +207,67 @@ fn find_ptr(&self) -> Option<uint> {
             }
 
             // The general case.
-            let discr = ~[ty::mk_uint()];
-            return General(cases.map(|c| mk_struct(cx, discr + c.tys, false)))
+            assert!((cases.len() - 1) as i64 >= 0);
+            let bounds = IntBounds { ulo: 0, uhi: (cases.len() - 1) as u64,
+                                     slo: 0, shi: (cases.len() - 1) as i64 };
+            let ity = range_to_inttype(cx, hint, &bounds);
+            let discr = ~[ty_of_inttype(ity)];
+            return General(ity, cases.map(|c| mk_struct(cx, discr + c.tys, false)))
         }
         _ => cx.sess.bug("adt::represent_type called on non-ADT type")
     }
 }
 
+/// Determine, without doing translation, whether an ADT must be FFI-safe.
+/// For use in lint or similar, where being sound but slightly incomplete is acceptable.
+pub fn is_ffi_safe(tcx: ty::ctxt, def_id: ast::DefId) -> bool {
+    match ty::get(ty::lookup_item_type(tcx, def_id).ty).sty {
+        ty::ty_enum(def_id, _) => {
+            let variants = ty::enum_variants(tcx, def_id);
+            // Univariant => like struct/tuple.
+            if variants.len() <= 1 {
+                return true;
+            }
+            let hint = ty::lookup_repr_hint(tcx, def_id);
+            // Appropriate representation explicitly selected?
+            if hint.is_ffi_safe() {
+                return true;
+            }
+            // Option<~T> and similar are used in FFI.  Rather than try to resolve type parameters
+            // and recognize this case exactly, this overapproximates -- assuming that if a
+            // non-C-like enum is being used in FFI then the user knows what they're doing.
+            if variants.iter().any(|vi| !vi.args.is_empty()) {
+                return true;
+            }
+            false
+        }
+        // struct, tuple, etc.
+        // (is this right in the present of typedefs?)
+        _ => true
+    }
+}
+
+// NOTE this should probably all be in ty
+struct Case { discr: Disr, tys: ~[ty::t] }
+impl Case {
+    fn is_zerolen(&self, cx: &mut CrateContext) -> bool {
+        mk_struct(cx, self.tys, false).size == 0
+    }
+    fn find_ptr(&self) -> Option<uint> {
+        self.tys.iter().position(|&ty| mono_data_classify(ty) == MonoNonNull)
+    }
+}
+
+fn get_cases(tcx: ty::ctxt, def_id: ast::DefId, substs: &ty::substs) -> ~[Case] {
+    do ty::enum_variants(tcx, def_id).map |vi| {
+        let arg_tys = do vi.args.map |&raw_ty| {
+            ty::subst(tcx, substs, raw_ty)
+        };
+        Case { discr: vi.disr_val, tys: arg_tys }
+    }
+}
+
+
 fn mk_struct(cx: &mut CrateContext, tys: &[ty::t], packed: bool) -> Struct {
     let lltys = tys.map(|&ty| type_of::sizing_type_of(cx, ty));
     let llty_rec = Type::struct_(lltys, packed);
@@ -225,6 +279,92 @@ fn mk_struct(cx: &mut CrateContext, tys: &[ty::t], packed: bool) -> Struct {
     }
 }
 
+struct IntBounds {
+    slo: i64,
+    shi: i64,
+    ulo: u64,
+    uhi: u64
+}
+
+fn mk_cenum(cx: &mut CrateContext, hint: Hint, bounds: &IntBounds) -> Repr {
+    let it = range_to_inttype(cx, hint, bounds);
+    match it {
+        attr::SignedInt(_) => CEnum(it, bounds.slo as Disr, bounds.shi as Disr),
+        attr::UnsignedInt(_) => CEnum(it, bounds.ulo, bounds.uhi)
+    }
+}
+
+fn range_to_inttype(cx: &mut CrateContext, hint: Hint, bounds: &IntBounds) -> IntType {
+    debug!("range_to_inttype: {:?} {:?}", hint, bounds);
+    // Lists of sizes to try.  u64 is always allowed as a fallback.
+    static choose_shortest: &'static[IntType] = &[
+        attr::UnsignedInt(ast::ty_u8), attr::SignedInt(ast::ty_i8),
+        attr::UnsignedInt(ast::ty_u16), attr::SignedInt(ast::ty_i16),
+        attr::UnsignedInt(ast::ty_u32), attr::SignedInt(ast::ty_i32)];
+    static at_least_32: &'static[IntType] = &[
+        attr::UnsignedInt(ast::ty_u32), attr::SignedInt(ast::ty_i32)];
+
+    let attempts;
+    match hint {
+        attr::ReprInt(span, ity) => {
+            if !bounds_usable(cx, ity, bounds) {
+                cx.sess.span_bug(span, "representation hint insufficient for discriminant range")
+            }
+            return ity;
+        }
+        attr::ReprExtern => {
+            attempts = match cx.sess.targ_cfg.arch {
+                X86 | X86_64 => at_least_32,
+                // WARNING: the ARM EABI has two variants; the one corresponding to `at_least_32`
+                // appears to be used on Linux and NetBSD, but some systems may use the variant
+                // corresponding to `choose_shortest`.  However, we don't run on those yet...?
+                Arm => at_least_32,
+                Mips => at_least_32,
+            }
+        }
+        attr::ReprAny => {
+            attempts = choose_shortest;
+        }
+    }
+    for &ity in attempts.iter() {
+        if bounds_usable(cx, ity, bounds) {
+            return ity;
+        }
+    }
+    return attr::UnsignedInt(ast::ty_u64);
+}
+
+pub fn ll_inttype(cx: &mut CrateContext, ity: IntType) -> Type {
+    match ity {
+        attr::SignedInt(t) => Type::int_from_ty(cx, t),
+        attr::UnsignedInt(t) => Type::uint_from_ty(cx, t)
+    }
+}
+
+fn bounds_usable(cx: &mut CrateContext, ity: IntType, bounds: &IntBounds) -> bool {
+    debug!("bounds_usable: {:?} {:?}", ity, bounds);
+    match ity {
+        attr::SignedInt(_) => {
+            let lllo = C_integral(ll_inttype(cx, ity), bounds.slo as u64, true);
+            let llhi = C_integral(ll_inttype(cx, ity), bounds.shi as u64, true);
+            bounds.slo == const_to_int(lllo) as i64 && bounds.shi == const_to_int(llhi) as i64
+        }
+        attr::UnsignedInt(_) => {
+            let lllo = C_integral(ll_inttype(cx, ity), bounds.ulo, false);
+            let llhi = C_integral(ll_inttype(cx, ity), bounds.uhi, false);
+            bounds.ulo == const_to_uint(lllo) as u64 && bounds.uhi == const_to_uint(llhi) as u64
+        }
+    }
+}
+
+pub fn ty_of_inttype(ity: IntType) -> ty::t {
+    match ity {
+        attr::SignedInt(t) => ty::mk_mach_int(t),
+        attr::UnsignedInt(t) => ty::mk_mach_uint(t)
+    }
+}
+
+
 /**
  * Returns the fields of a struct for the given representation.
  * All nominal types are LLVM structs, in order to be able to use
@@ -239,33 +379,41 @@ pub fn sizing_fields_of(cx: &mut CrateContext, r: &Repr) -> ~[Type] {
 }
 fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) -> ~[Type] {
     match *r {
-        CEnum(*) => ~[Type::enum_discrim(cx)],
+        CEnum(ity, _, _) => ~[ll_inttype(cx, ity)],
         Univariant(ref st, _dtor) => struct_llfields(cx, st, sizing),
         NullablePointer{ nonnull: ref st, _ } => struct_llfields(cx, st, sizing),
-        General(ref sts) => {
-            // To get "the" type of a general enum, we pick the case
-            // with the largest alignment (so it will always align
-            // correctly in containing structures) and pad it out.
-            assert!(sts.len() >= 1);
-            let mut most_aligned = None;
-            let mut largest_align = 0;
-            let mut largest_size = 0;
-            for st in sts.iter() {
-                if largest_size < st.size {
-                    largest_size = st.size;
-                }
-                if largest_align < st.align {
-                    // Clang breaks ties by size; it is unclear if
-                    // that accomplishes anything important.
-                    largest_align = st.align;
-                    most_aligned = Some(st);
-                }
-            }
-            let most_aligned = most_aligned.unwrap();
-            let padding = largest_size - most_aligned.size;
-
-            struct_llfields(cx, most_aligned, sizing)
-                + &[Type::array(&Type::i8(), padding)]
+        General(ity, ref sts) => {
+            // We need a representation that has:
+            // * The alignment of the most-aligned field
+            // * The size of the largest variant (rounded up to that alignment)
+            // * No alignment padding anywhere any variant has actual data
+            //   (currently matters only for enums small enough to be immediate)
+            // * The discriminant in an obvious place.
+            //
+            // So we start with the discriminant, pad it up to the alignment with
+            // more of its own type, then use alignment-sized ints to get the rest
+            // of the size.
+            //
+            // Note: if/when we start exposing SIMD vector types (or f80, on some
+            // platforms that have it), this will need some adjustment.
+            let size = sts.iter().map(|st| st.size).max().unwrap();
+            let most_aligned = sts.iter().max_by(|st| st.align).unwrap();
+            let align = most_aligned.align;
+            let discr_ty = ll_inttype(cx, ity);
+            let discr_size = machine::llsize_of_alloc(cx, discr_ty) as u64;
+            let pad_ty = match align {
+                1 => Type::i8(),
+                2 => Type::i16(),
+                4 => Type::i32(),
+                8 if machine::llalign_of_min(cx, Type::i64()) == 8 => Type::i64(),
+                _ => fail!("Unsupported enum alignment: {:?}", align)
+            };
+            assert_eq!(machine::llalign_of_min(cx, pad_ty) as u64, align);
+            let align_units = (size + align - 1) / align;
+            assert_eq!(align % discr_size, 0);
+            ~[discr_ty,
+              Type::array(&discr_ty, align / discr_size - 1),
+              Type::array(&pad_ty, align_units - 1)]
         }
     }
 }
@@ -288,7 +436,7 @@ pub fn trans_switch(bcx: @mut Block, r: &Repr, scrutinee: ValueRef)
     -> (_match::branch_kind, Option<ValueRef>) {
     match *r {
         CEnum(*) | General(*) => {
-            (_match::switch, Some(trans_get_discr(bcx, r, scrutinee)))
+            (_match::switch, Some(trans_get_discr(bcx, r, scrutinee, None)))
         }
         NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => {
             (_match::switch, Some(nullable_bitdiscr(bcx, nonnull, nndiscr, ptrfield, scrutinee)))
@@ -302,17 +450,32 @@ pub fn trans_switch(bcx: @mut Block, r: &Repr, scrutinee: ValueRef)
 
 
 /// Obtain the actual discriminant of a value.
-pub fn trans_get_discr(bcx: @mut Block, r: &Repr, scrutinee: ValueRef)
+pub fn trans_get_discr(bcx: @mut Block, r: &Repr, scrutinee: ValueRef, cast_to: Option<Type>)
     -> ValueRef {
+    let signed;
+    let val;
     match *r {
-        CEnum(min, max) => load_discr(bcx, scrutinee, min, max),
-        Univariant(*) => C_disr(bcx.ccx(), 0),
-        General(ref cases) => load_discr(bcx, scrutinee, 0, (cases.len() - 1) as Disr),
+        CEnum(ity, min, max) => {
+            val = load_discr(bcx, ity, scrutinee, min, max);
+            signed = ity.is_signed();
+        }
+        General(ity, ref cases) => {
+            val = load_discr(bcx, ity, scrutinee, 0, (cases.len() - 1) as Disr);
+            signed = ity.is_signed();
+        }
+        Univariant(*) => {
+            val = C_u8(0);
+            signed = false;
+        }
         NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => {
-            ZExt(bcx, nullable_bitdiscr(bcx, nonnull, nndiscr, ptrfield, scrutinee),
-                 Type::enum_discrim(bcx.ccx()))
+            val = nullable_bitdiscr(bcx, nonnull, nndiscr, ptrfield, scrutinee);
+            signed = false;
         }
     }
+    match cast_to {
+        None => val,
+        Some(llty) => if signed { SExt(bcx, val, llty) } else { ZExt(bcx, val, llty) }
+    }
 }
 
 fn nullable_bitdiscr(bcx: @mut Block, nonnull: &Struct, nndiscr: Disr, ptrfield: uint,
@@ -324,10 +487,15 @@ fn nullable_bitdiscr(bcx: @mut Block, nonnull: &Struct, nndiscr: Disr, ptrfield:
 }
 
 /// Helper for cases where the discriminant is simply loaded.
-fn load_discr(bcx: @mut Block, scrutinee: ValueRef, min: Disr, max: Disr)
+fn load_discr(bcx: @mut Block, ity: IntType, scrutinee: ValueRef, min: Disr, max: Disr)
     -> ValueRef {
     let ptr = GEPi(bcx, scrutinee, [0, 0]);
-    if max + 1 == min {
+    let llty = ll_inttype(bcx.ccx(), ity);
+    assert_eq!(val_ty(ptr), llty.ptr_to());
+    let bits = machine::llbitsize_of_real(bcx.ccx(), llty);
+    assert!(bits <= 64);
+    let mask = (-1u64 >> (64 - bits)) as Disr;
+    if (max + 1) & mask == min & mask {
         // i.e., if the range is everything.  The lo==hi case would be
         // rejected by the LLVM verifier (it would mean either an
         // empty set, which is impossible, or the entire range of the
@@ -350,15 +518,17 @@ fn load_discr(bcx: @mut Block, scrutinee: ValueRef, min: Disr, max: Disr)
  */
 pub fn trans_case(bcx: @mut Block, r: &Repr, discr: Disr) -> _match::opt_result {
     match *r {
-        CEnum(*) => {
-            _match::single_result(rslt(bcx, C_disr(bcx.ccx(), discr)))
+        CEnum(ity, _, _) => {
+            _match::single_result(rslt(bcx, C_integral(ll_inttype(bcx.ccx(), ity),
+                                                       discr as u64, true)))
+        }
+        General(ity, _) => {
+            _match::single_result(rslt(bcx, C_integral(ll_inttype(bcx.ccx(), ity),
+                                                       discr as u64, true)))
         }
         Univariant(*) => {
             bcx.ccx().sess.bug("no cases for univariants or structs")
         }
-        General(*) => {
-            _match::single_result(rslt(bcx, C_disr(bcx.ccx(), discr)))
-        }
         NullablePointer{ _ } => {
             assert!(discr == 0 || discr == 1);
             _match::single_result(rslt(bcx, C_i1(discr != 0)))
@@ -373,9 +543,14 @@ pub fn trans_case(bcx: @mut Block, r: &Repr, discr: Disr) -> _match::opt_result
  */
 pub fn trans_start_init(bcx: @mut Block, r: &Repr, val: ValueRef, discr: Disr) {
     match *r {
-        CEnum(min, max) => {
-            assert!(min <= discr && discr <= max);
-            Store(bcx, C_disr(bcx.ccx(), discr), GEPi(bcx, val, [0, 0]))
+        CEnum(ity, min, max) => {
+            assert_discr_in_range(ity, min, max, discr);
+            Store(bcx, C_integral(ll_inttype(bcx.ccx(), ity), discr as u64, true),
+                  GEPi(bcx, val, [0, 0]))
+        }
+        General(ity, _) => {
+            Store(bcx, C_integral(ll_inttype(bcx.ccx(), ity), discr as u64, true),
+                  GEPi(bcx, val, [0, 0]))
         }
         Univariant(ref st, true) => {
             assert_eq!(discr, 0);
@@ -385,9 +560,6 @@ pub fn trans_start_init(bcx: @mut Block, r: &Repr, val: ValueRef, discr: Disr) {
         Univariant(*) => {
             assert_eq!(discr, 0);
         }
-        General(*) => {
-            Store(bcx, C_disr(bcx.ccx(), discr), GEPi(bcx, val, [0, 0]))
-        }
         NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => {
             if discr != nndiscr {
                 let llptrptr = GEPi(bcx, val, [0, ptrfield]);
@@ -398,6 +570,13 @@ pub fn trans_start_init(bcx: @mut Block, r: &Repr, val: ValueRef, discr: Disr) {
     }
 }
 
+fn assert_discr_in_range(ity: IntType, min: Disr, max: Disr, discr: Disr) {
+    match ity {
+        attr::UnsignedInt(_) => assert!(min <= discr && discr <= max),
+        attr::SignedInt(_) => assert!(min as i64 <= discr as i64 && discr as i64 <= max as i64)
+    }
+}
+
 /**
  * The number of fields in a given case; for use when obtaining this
  * information from the type or definition is less convenient.
@@ -409,7 +588,7 @@ pub fn num_args(r: &Repr, discr: Disr) -> uint {
             assert_eq!(discr, 0);
             st.fields.len() - (if dtor { 1 } else { 0 })
         }
-        General(ref cases) => cases[discr].fields.len() - 1,
+        General(_, ref cases) => cases[discr].fields.len() - 1,
         NullablePointer{ nonnull: ref nonnull, nndiscr, nullfields: ref nullfields, _ } => {
             if discr == nndiscr { nonnull.fields.len() } else { nullfields.len() }
         }
@@ -430,7 +609,7 @@ pub fn trans_field_ptr(bcx: @mut Block, r: &Repr, val: ValueRef, discr: Disr,
             assert_eq!(discr, 0);
             struct_field_ptr(bcx, st, val, ix, false)
         }
-        General(ref cases) => {
+        General(_, ref cases) => {
             struct_field_ptr(bcx, &cases[discr], val, ix + 1, true)
         }
         NullablePointer{ nonnull: ref nonnull, nullfields: ref nullfields, nndiscr, _ } => {
@@ -498,24 +677,23 @@ pub fn trans_drop_flag_ptr(bcx: @mut Block, r: &Repr, val: ValueRef) -> ValueRef
 pub fn trans_const(ccx: &mut CrateContext, r: &Repr, discr: Disr,
                    vals: &[ValueRef]) -> ValueRef {
     match *r {
-        CEnum(min, max) => {
+        CEnum(ity, min, max) => {
             assert_eq!(vals.len(), 0);
-            assert!(min <= discr && discr <= max);
-            C_disr(ccx, discr)
+            assert_discr_in_range(ity, min, max, discr);
+            C_integral(ll_inttype(ccx, ity), discr as u64, true)
         }
-        Univariant(ref st, _dro) => {
-            assert_eq!(discr, 0);
-            let contents = build_const_struct(ccx, st, vals);
-            C_struct(contents, st.packed)
-        }
-        General(ref cases) => {
+        General(ity, ref cases) => {
             let case = &cases[discr];
             let max_sz = cases.iter().map(|x| x.size).max().unwrap();
-            let discr_ty = C_disr(ccx, discr);
-            let contents = build_const_struct(ccx, case,
-                                              ~[discr_ty] + vals);
+            let lldiscr = C_integral(ll_inttype(ccx, ity), discr as u64, true);
+            let contents = build_const_struct(ccx, case, ~[lldiscr] + vals);
             C_struct(contents + &[padding(max_sz - case.size)], false)
         }
+        Univariant(ref st, _dro) => {
+            assert!(discr == 0);
+            let contents = build_const_struct(ccx, st, vals);
+            C_struct(contents, st.packed)
+        }
         NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => {
             if discr == nndiscr {
                 C_struct(build_const_struct(ccx, nonnull, vals), false)
@@ -585,9 +763,19 @@ fn roundup(x: u64, a: u64) -> u64 { ((x + (a - 1)) / a) * a }
 pub fn const_get_discrim(ccx: &mut CrateContext, r: &Repr, val: ValueRef)
     -> Disr {
     match *r {
-        CEnum(*) => const_to_uint(val) as Disr,
+        CEnum(ity, _, _) => {
+            match ity {
+                attr::SignedInt(*) => const_to_int(val) as Disr,
+                attr::UnsignedInt(*) => const_to_uint(val) as Disr
+            }
+        }
+        General(ity, _) => {
+            match ity {
+                attr::SignedInt(*) => const_to_int(const_get_elt(ccx, val, [0])) as Disr,
+                attr::UnsignedInt(*) => const_to_uint(const_get_elt(ccx, val, [0])) as Disr
+            }
+        }
         Univariant(*) => 0,
-        General(*) => const_to_uint(const_get_elt(ccx, val, [0])) as Disr,
         NullablePointer{ nndiscr, ptrfield, _ } => {
             if is_null(const_struct_field(ccx, val, ptrfield)) {
                 /* subtraction as uint is ok because nndiscr is either 0 or 1 */
@@ -646,7 +834,3 @@ pub fn is_newtypeish(r: &Repr) -> bool {
         _ => false
     }
 }
-
-fn C_disr(cx: &CrateContext, i: Disr) -> ValueRef {
-    return C_integral(cx.int_type, i, false);
-}
index 560cfa4be6bbf734a3d8170fec7538a6e37ea9b3..c002584a7fff93e1bd51e7fd8d9530461eef9420 100644 (file)
@@ -868,6 +868,10 @@ pub fn C_i64(i: i64) -> ValueRef {
     return C_integral(Type::i64(), i as u64, true);
 }
 
+pub fn C_u64(i: u64) -> ValueRef {
+    return C_integral(Type::i64(), i, false);
+}
+
 pub fn C_int(cx: &CrateContext, i: int) -> ValueRef {
     return C_integral(cx.int_type, i as u64, true);
 }
index cea39c8e3d252e89ab5b9a2fd61ddcba16e5c386..0a5a9b3b5c18338f5c5d61697093f3ccc5a97247 100644 (file)
@@ -1251,7 +1251,7 @@ fn create_member_descriptions(&self, cx: &mut CrateContext)
                                   -> ~[MemberDescription] {
         // Capture type_rep, so we don't have to copy the struct_defs array
         let struct_defs = match *self.type_rep {
-            adt::General(ref struct_defs) => struct_defs,
+            adt::General(_, ref struct_defs) => struct_defs,
             _ => cx.sess.bug("unreachable")
         };
 
@@ -1400,14 +1400,6 @@ fn prepare_enum_metadata(cx: &mut CrateContext,
         return FinalMetadata(empty_type_metadata);
     }
 
-    // Prepare some data (llvm type, size, align, etc) about the discriminant. This data will be
-    // needed in all of the following cases.
-    let discriminant_llvm_type = Type::enum_discrim(cx);
-    let (discriminant_size, discriminant_align) = size_and_align_of(cx, discriminant_llvm_type);
-
-    assert!(Type::enum_discrim(cx) == cx.int_type);
-    let discriminant_base_type_metadata = type_metadata(cx, ty::mk_int(), codemap::dummy_sp());
-
     let variants = ty::enum_variants(cx.tcx, enum_def_id);
 
     let enumerators_metadata: ~[DIDescriptor] = variants
@@ -1427,26 +1419,32 @@ fn prepare_enum_metadata(cx: &mut CrateContext,
         })
         .collect();
 
-    let discriminant_type_metadata = do enum_name.with_c_str |enum_name| {
-        unsafe {
-            llvm::LLVMDIBuilderCreateEnumerationType(
-                DIB(cx),
-                containing_scope,
-                enum_name,
-                file_metadata,
-                loc.line as c_uint,
-                bytes_to_bits(discriminant_size),
-                bytes_to_bits(discriminant_align),
-                create_DIArray(DIB(cx), enumerators_metadata),
-                discriminant_base_type_metadata)
+    let discriminant_type_metadata = |inttype| {
+        let discriminant_llvm_type = adt::ll_inttype(cx, inttype);
+        let (discriminant_size, discriminant_align) = size_and_align_of(cx, discriminant_llvm_type);
+        let discriminant_base_type_metadata = type_metadata(cx, adt::ty_of_inttype(inttype),
+                                                            codemap::dummy_sp());
+        do enum_name.with_c_str |enum_name| {
+            unsafe {
+                llvm::LLVMDIBuilderCreateEnumerationType(
+                    DIB(cx),
+                    containing_scope,
+                    enum_name,
+                    file_metadata,
+                    loc.line as c_uint,
+                    bytes_to_bits(discriminant_size),
+                    bytes_to_bits(discriminant_align),
+                    create_DIArray(DIB(cx), enumerators_metadata),
+                    discriminant_base_type_metadata)
+            }
         }
     };
 
     let type_rep = adt::represent_type(cx, enum_type);
 
     return match *type_rep {
-        adt::CEnum(*) => {
-            FinalMetadata(discriminant_type_metadata)
+        adt::CEnum(inttype, _, _) => {
+            FinalMetadata(discriminant_type_metadata(inttype))
         }
         adt::Univariant(ref struct_def, _) => {
             assert!(variants.len() == 1);
@@ -1467,7 +1465,8 @@ fn prepare_enum_metadata(cx: &mut CrateContext,
                 member_description_factory: member_description_factory
             }
         }
-        adt::General(_) => {
+        adt::General(inttype, _) => {
+            let discriminant_type_metadata = discriminant_type_metadata(inttype);
             let enum_llvm_type = type_of::type_of(cx, enum_type);
             let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
 
index ca1bd2d8a957fdbd74e9fc146cd762894285d3e3..f291f088dec6c04a3fdbd6c7b18596776592ca64 100644 (file)
@@ -1727,9 +1727,14 @@ fn trans_imm_cast(bcx: @mut Block, expr: &ast::Expr,
             (cast_enum, cast_float) => {
                 let bcx = bcx;
                 let repr = adt::represent_type(ccx, t_in);
-                let slot = Alloca(bcx, ll_t_in, "");
-                Store(bcx, llexpr, slot);
-                let lldiscrim_a = adt::trans_get_discr(bcx, repr, slot);
+                let llexpr_ptr;
+                if type_is_immediate(ccx, t_in) {
+                    llexpr_ptr = Alloca(bcx, ll_t_in, "");
+                    Store(bcx, llexpr, llexpr_ptr);
+                } else {
+                    llexpr_ptr = llexpr;
+                }
+                let lldiscrim_a = adt::trans_get_discr(bcx, repr, llexpr_ptr, Some(Type::i64()));
                 match k_out {
                     cast_integral => int_cast(bcx, ll_t_out,
                                               val_ty(lldiscrim_a),
index 54ecc15c44f7072439599b1d12f0cb91f881cd05..7e875243fd0832b2aece2333eb740733ca0ce1e2 100644 (file)
@@ -25,7 +25,7 @@
 use util::ppaux::ty_to_str;
 
 use std::libc::c_uint;
-use std::option::None;
+use std::option::{Some,None};
 use std::vec;
 use syntax::ast::DefId;
 use syntax::ast;
@@ -292,11 +292,11 @@ pub fn visit_ty(&mut self, t: ty::t) {
                                                                sub_path,
                                                                "get_disr");
 
-                let llfdecl = decl_internal_rust_fn(ccx, [opaqueptrty], ty::mk_int(), sym);
+                let llfdecl = decl_internal_rust_fn(ccx, [opaqueptrty], ty::mk_u64(), sym);
                 let fcx = new_fn_ctxt(ccx,
                                       ~[],
                                       llfdecl,
-                                      ty::mk_uint(),
+                                      ty::mk_u64(),
                                       None);
                 let arg = unsafe {
                     //
@@ -308,7 +308,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
                 };
                 let mut bcx = fcx.entry_bcx.unwrap();
                 let arg = BitCast(bcx, arg, llptrty);
-                let ret = adt::trans_get_discr(bcx, repr, arg);
+                let ret = adt::trans_get_discr(bcx, repr, arg, Some(Type::i64()));
                 Store(bcx, ret, fcx.llretptr.unwrap());
                 match fcx.llreturn {
                     Some(llreturn) => cleanup_and_Br(bcx, bcx, llreturn),
@@ -324,7 +324,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
                 for (i, v) in variants.iter().enumerate() {
                     let name = ccx.sess.str_of(v.name);
                     let variant_args = ~[this.c_uint(i),
-                                         C_integral(self.bcx.ccx().int_type, v.disr_val, false),
+                                         C_u64(v.disr_val),
                                          this.c_uint(v.args.len()),
                                          this.c_slice(name)];
                     do this.bracketed("enum_variant", variant_args) |this| {
index 38c5e0b55f741a503fbf983bcb719292c6ae2683..1f9e9037179313b0375ab0a0942558ada62fd8df 100644 (file)
@@ -22,7 +22,7 @@
 use middle::trans::expr::{Dest, Ignore, SaveIn};
 use middle::trans::expr;
 use middle::trans::glue;
-use middle::trans::machine::{llsize_of, nonzero_llsize_of};
+use middle::trans::machine::{llsize_of, nonzero_llsize_of, llsize_of_alloc};
 use middle::trans::type_of;
 use middle::ty;
 use util::common::indenter;
@@ -144,16 +144,19 @@ pub struct VecTypes {
     vec_ty: ty::t,
     unit_ty: ty::t,
     llunit_ty: Type,
-    llunit_size: ValueRef
+    llunit_size: ValueRef,
+    llunit_alloc_size: uint
 }
 
 impl VecTypes {
     pub fn to_str(&self, ccx: &CrateContext) -> ~str {
-        format!("VecTypes \\{vec_ty={}, unit_ty={}, llunit_ty={}, llunit_size={}\\}",
+        format!("VecTypes \\{vec_ty={}, unit_ty={}, llunit_ty={}, llunit_size={}, \
+                 llunit_alloc_size={}\\}",
              ty_to_str(ccx.tcx, self.vec_ty),
              ty_to_str(ccx.tcx, self.unit_ty),
              ccx.tn.type_to_str(self.llunit_ty),
-             ccx.tn.val_to_str(self.llunit_size))
+             ccx.tn.val_to_str(self.llunit_size),
+             self.llunit_alloc_size)
     }
 }
 
@@ -416,48 +419,10 @@ pub fn write_content(bcx: @mut Block,
                         expr::trans_to_datum(bcx, element)
                     });
 
-                    let next_bcx = sub_block(bcx, "expr_repeat: while next");
-                    let loop_bcx = loop_scope_block(bcx, next_bcx, None, "expr_repeat", None);
-                    let cond_bcx = scope_block(loop_bcx, None, "expr_repeat: loop cond");
-                    let set_bcx = scope_block(loop_bcx, None, "expr_repeat: body: set");
-                    let inc_bcx = scope_block(loop_bcx, None, "expr_repeat: body: inc");
-                    Br(bcx, loop_bcx.llbb);
-
-                    let loop_counter = {
-                        // i = 0
-                        let i = alloca(loop_bcx, bcx.ccx().int_type, "__i");
-                        Store(loop_bcx, C_uint(bcx.ccx(), 0), i);
-
-                        Br(loop_bcx, cond_bcx.llbb);
-                        i
-                    };
-
-                    { // i < count
-                        let lhs = Load(cond_bcx, loop_counter);
-                        let rhs = C_uint(bcx.ccx(), count);
-                        let cond_val = ICmp(cond_bcx, lib::llvm::IntULT, lhs, rhs);
-
-                        CondBr(cond_bcx, cond_val, set_bcx.llbb, next_bcx.llbb);
-                    }
-
-                    { // v[i] = elem
-                        let i = Load(set_bcx, loop_counter);
-                        let lleltptr = InBoundsGEP(set_bcx, lldest, [i]);
-                        let set_bcx = elem.copy_to(set_bcx, INIT, lleltptr);
-
-                        Br(set_bcx, inc_bcx.llbb);
-                    }
-
-                    { // i += 1
-                        let i = Load(inc_bcx, loop_counter);
-                        let plusone = Add(inc_bcx, i, C_uint(bcx.ccx(), 1));
-                        Store(inc_bcx, plusone, loop_counter);
-
-                        Br(inc_bcx, cond_bcx.llbb);
-                    }
-
-                    return next_bcx;
-
+                    iter_vec_loop(bcx, lldest, vt,
+                                  C_uint(bcx.ccx(), count), |set_bcx, lleltptr, _| {
+                        elem.copy_to(set_bcx, INIT, lleltptr)
+                    })
                 }
             }
         }
@@ -478,11 +443,13 @@ pub fn vec_types(bcx: @mut Block, vec_ty: ty::t) -> VecTypes {
     let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
     let llunit_ty = type_of::type_of(ccx, unit_ty);
     let llunit_size = nonzero_llsize_of(ccx, llunit_ty);
+    let llunit_alloc_size = llsize_of_alloc(ccx, llunit_ty);
 
     VecTypes {vec_ty: vec_ty,
               unit_ty: unit_ty,
               llunit_ty: llunit_ty,
-              llunit_size: llunit_size}
+              llunit_size: llunit_size,
+              llunit_alloc_size: llunit_alloc_size}
 }
 
 pub fn elements_required(bcx: @mut Block, content_expr: &ast::Expr) -> uint {
@@ -574,35 +541,94 @@ pub fn get_base_and_len(bcx: @mut Block, llval: ValueRef, vec_ty: ty::t) -> (Val
 
 pub type iter_vec_block<'self> = &'self fn(@mut Block, ValueRef, ty::t) -> @mut Block;
 
+pub fn iter_vec_loop(bcx: @mut Block,
+                     data_ptr: ValueRef,
+                     vt: &VecTypes,
+                     count: ValueRef,
+                     f: iter_vec_block
+                     ) -> @mut Block {
+    let _icx = push_ctxt("tvec::iter_vec_loop");
+
+    let next_bcx = sub_block(bcx, "iter_vec_loop: while next");
+    let loop_bcx = loop_scope_block(bcx, next_bcx, None, "iter_vec_loop", None);
+    let cond_bcx = scope_block(loop_bcx, None, "iter_vec_loop: loop cond");
+    let body_bcx = scope_block(loop_bcx, None, "iter_vec_loop: body: main");
+    let inc_bcx = scope_block(loop_bcx, None, "iter_vec_loop: loop inc");
+    Br(bcx, loop_bcx.llbb);
+
+    let loop_counter = {
+        // i = 0
+        let i = alloca(loop_bcx, bcx.ccx().int_type, "__i");
+        Store(loop_bcx, C_uint(bcx.ccx(), 0), i);
+
+        Br(loop_bcx, cond_bcx.llbb);
+        i
+    };
+
+    { // i < count
+        let lhs = Load(cond_bcx, loop_counter);
+        let rhs = count;
+        let cond_val = ICmp(cond_bcx, lib::llvm::IntULT, lhs, rhs);
+
+        CondBr(cond_bcx, cond_val, body_bcx.llbb, next_bcx.llbb);
+    }
+
+    { // loop body
+        let i = Load(body_bcx, loop_counter);
+        let lleltptr = if vt.llunit_alloc_size == 0 {
+            data_ptr
+        } else {
+            InBoundsGEP(body_bcx, data_ptr, [i])
+        };
+        let body_bcx = f(body_bcx, lleltptr, vt.unit_ty);
+
+        Br(body_bcx, inc_bcx.llbb);
+    }
+
+    { // i += 1
+        let i = Load(inc_bcx, loop_counter);
+        let plusone = Add(inc_bcx, i, C_uint(bcx.ccx(), 1));
+        Store(inc_bcx, plusone, loop_counter);
+
+        Br(inc_bcx, cond_bcx.llbb);
+    }
+
+    next_bcx
+}
+
 pub fn iter_vec_raw(bcx: @mut Block, data_ptr: ValueRef, vec_ty: ty::t,
                     fill: ValueRef, f: iter_vec_block) -> @mut Block {
     let _icx = push_ctxt("tvec::iter_vec_raw");
 
-    let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
-
-    // Calculate the last pointer address we want to handle.
-    // FIXME (#3729): Optimize this when the size of the unit type is
-    // statically known to not use pointer casts, which tend to confuse
-    // LLVM.
-    let data_end_ptr = pointer_add_byte(bcx, data_ptr, fill);
-
-    // Now perform the iteration.
-    let header_bcx = base::sub_block(bcx, "iter_vec_loop_header");
-    Br(bcx, header_bcx.llbb);
-    let data_ptr =
-        Phi(header_bcx, val_ty(data_ptr), [data_ptr], [bcx.llbb]);
-    let not_yet_at_end =
-        ICmp(header_bcx, lib::llvm::IntULT, data_ptr, data_end_ptr);
-    let body_bcx = base::sub_block(header_bcx, "iter_vec_loop_body");
-    let next_bcx = base::sub_block(header_bcx, "iter_vec_next");
-    CondBr(header_bcx, not_yet_at_end, body_bcx.llbb, next_bcx.llbb);
-    let body_bcx = f(body_bcx, data_ptr, unit_ty);
-    AddIncomingToPhi(data_ptr, InBoundsGEP(body_bcx, data_ptr,
-                                           [C_int(bcx.ccx(), 1)]),
-                     body_bcx.llbb);
-    Br(body_bcx, header_bcx.llbb);
-    return next_bcx;
+    let vt = vec_types(bcx, vec_ty);
+    if (vt.llunit_alloc_size == 0) {
+        // Special-case vectors with elements of size 0  so they don't go out of bounds (#9890)
+        iter_vec_loop(bcx, data_ptr, &vt, fill, f)
+    } else {
+        // Calculate the last pointer address we want to handle.
+        // FIXME (#3729): Optimize this when the size of the unit type is
+        // statically known to not use pointer casts, which tend to confuse
+        // LLVM.
+        let data_end_ptr = pointer_add_byte(bcx, data_ptr, fill);
+
+        // Now perform the iteration.
+        let header_bcx = base::sub_block(bcx, "iter_vec_loop_header");
+        Br(bcx, header_bcx.llbb);
+        let data_ptr =
+            Phi(header_bcx, val_ty(data_ptr), [data_ptr], [bcx.llbb]);
+        let not_yet_at_end =
+            ICmp(header_bcx, lib::llvm::IntULT, data_ptr, data_end_ptr);
+        let body_bcx = base::sub_block(header_bcx, "iter_vec_loop_body");
+        let next_bcx = base::sub_block(header_bcx, "iter_vec_next");
+        CondBr(header_bcx, not_yet_at_end, body_bcx.llbb, next_bcx.llbb);
+        let body_bcx = f(body_bcx, data_ptr, vt.unit_ty);
+        AddIncomingToPhi(data_ptr, InBoundsGEP(body_bcx, data_ptr,
+                                               [C_int(bcx.ccx(), 1)]),
+                         body_bcx.llbb);
+        Br(body_bcx, header_bcx.llbb);
+        next_bcx
 
+    }
 }
 
 pub fn iter_vec_uniq(bcx: @mut Block, vptr: ValueRef, vec_ty: ty::t,
index fbfac3b75187d9716e270f6b478e6c1892588c23..3f12f563bc47fe16af1765f513dd6271b110302f 100644 (file)
@@ -38,6 +38,7 @@
 use syntax::ast_util::is_local;
 use syntax::ast_util;
 use syntax::attr;
+use syntax::attr::AttrMetaMethods;
 use syntax::codemap::Span;
 use syntax::codemap;
 use syntax::parse::token;
@@ -715,6 +716,7 @@ pub struct ParamBounds {
 pub type BuiltinBounds = EnumSet<BuiltinBound>;
 
 #[deriving(Clone, Eq, IterBytes, ToStr)]
+#[repr(uint)]
 pub enum BuiltinBound {
     BoundStatic,
     BoundSend,
@@ -4102,27 +4104,42 @@ pub fn lookup_trait_def(cx: ctxt, did: ast::DefId) -> @ty::TraitDef {
     }
 }
 
-/// Determine whether an item is annotated with an attribute
-pub fn has_attr(tcx: ctxt, did: DefId, attr: &str) -> bool {
+/// Iterate over meta_items of a definition.
+// (This should really be an iterator, but that would require csearch and
+// decoder to use iterators instead of higher-order functions.)
+pub fn each_attr(tcx: ctxt, did: DefId, f: &fn(@MetaItem) -> bool) -> bool {
     if is_local(did) {
         match tcx.items.find(&did.node) {
-            Some(
-                &ast_map::node_item(@ast::item {
-                    attrs: ref attrs,
-                    _
-                }, _)) => attr::contains_name(*attrs, attr),
+            Some(&ast_map::node_item(@ast::item {attrs: ref attrs, _}, _)) =>
+                attrs.iter().advance(|attr| f(attr.node.value)),
             _ => tcx.sess.bug(format!("has_attr: {:?} is not an item",
-                                   did))
+                                      did))
         }
     } else {
-        let mut ret = false;
+        let mut cont = true;
         do csearch::get_item_attrs(tcx.cstore, did) |meta_items| {
-            ret = ret || attr::contains_name(meta_items, attr);
+            if cont {
+                cont = meta_items.iter().advance(|ptrptr| f(*ptrptr));
+            }
         }
-        ret
+        return cont;
     }
 }
 
+/// Determine whether an item is annotated with an attribute
+pub fn has_attr(tcx: ctxt, did: DefId, attr: &str) -> bool {
+    let mut found = false;
+    each_attr(tcx, did, |item| {
+        if attr == item.name() {
+            found = true;
+            false
+        } else {
+            true
+        }
+    });
+    return found;
+}
+
 /// Determine whether an item is annotated with `#[packed]`
 pub fn lookup_packed(tcx: ctxt, did: DefId) -> bool {
     has_attr(tcx, did, "packed")
@@ -4133,6 +4150,16 @@ pub fn lookup_simd(tcx: ctxt, did: DefId) -> bool {
     has_attr(tcx, did, "simd")
 }
 
+// Obtain the the representation annotation for a definition.
+pub fn lookup_repr_hint(tcx: ctxt, did: DefId) -> attr::ReprAttr {
+    let mut acc = attr::ReprAny;
+    ty::each_attr(tcx, did, |meta| {
+        acc = attr::find_repr_attr(tcx.sess.diagnostic(), meta, acc);
+        true
+    });
+    return acc;
+}
+
 // Look up a field ID, whether or not it's local
 // Takes a list of type substs in case the struct is generic
 pub fn lookup_field_type(tcx: ctxt,
index ab6ed65d542f0f4eee0fda787962ee8b14dbbb3c..b0196010cb06b26786165d7c9284c141acd991cb 100644 (file)
 use syntax::ast_map;
 use syntax::ast_util::local_def;
 use syntax::ast_util;
+use syntax::attr;
 use syntax::codemap::Span;
 use syntax::codemap;
 use syntax::opt_vec::OptVec;
@@ -2372,6 +2373,11 @@ fn check_struct_enum_variant(fcx: @mut FnCtxt,
         let result_t = fcx.expr_ty(expr);
         demand::suptype(fcx, expr.span, result_t, lhs_t);
 
+        let tcx = fcx.tcx();
+        if !ty::expr_is_lval(tcx, fcx.ccx.method_map, lhs) {
+            tcx.sess.span_err(lhs.span, "illegal left-hand side expression");
+        }
+
         // Overwrite result of check_binop...this preserves existing behavior
         // but seems quite dubious with regard to user-defined methods
         // and so forth. - Niko
@@ -2544,6 +2550,12 @@ fn check_struct_enum_variant(fcx: @mut FnCtxt,
       }
       ast::ExprAssign(lhs, rhs) => {
         check_assignment(fcx, lhs, rhs, id);
+
+        let tcx = fcx.tcx();
+        if !ty::expr_is_lval(tcx, fcx.ccx.method_map, lhs) {
+            tcx.sess.span_err(lhs.span, "illegal left-hand side expression");
+        }
+
         let lhs_ty = fcx.expr_ty(lhs);
         let rhs_ty = fcx.expr_ty(rhs);
         if ty::type_is_error(lhs_ty) || ty::type_is_error(rhs_ty) {
@@ -3169,9 +3181,38 @@ pub fn check_enum_variants(ccx: @mut CrateCtxt,
                            sp: Span,
                            vs: &[ast::variant],
                            id: ast::NodeId) {
+
+    fn disr_in_range(ccx: @mut CrateCtxt,
+                     ty: attr::IntType,
+                     disr: ty::Disr) -> bool {
+        fn uint_in_range(ccx: @mut CrateCtxt, ty: ast::uint_ty, disr: ty::Disr) -> bool {
+            match ty {
+                ast::ty_u8 => disr as u8 as Disr == disr,
+                ast::ty_u16 => disr as u16 as Disr == disr,
+                ast::ty_u32 => disr as u32 as Disr == disr,
+                ast::ty_u64 => disr as u64 as Disr == disr,
+                ast::ty_u => uint_in_range(ccx, ccx.tcx.sess.targ_cfg.uint_type, disr)
+            }
+        }
+        fn int_in_range(ccx: @mut CrateCtxt, ty: ast::int_ty, disr: ty::Disr) -> bool {
+            match ty {
+                ast::ty_i8 => disr as i8 as Disr == disr,
+                ast::ty_i16 => disr as i16 as Disr == disr,
+                ast::ty_i32 => disr as i32 as Disr == disr,
+                ast::ty_i64 => disr as i64 as Disr == disr,
+                ast::ty_i => int_in_range(ccx, ccx.tcx.sess.targ_cfg.int_type, disr)
+            }
+        }
+        match ty {
+            attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
+            attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
+        }
+    }
+
     fn do_check(ccx: @mut CrateCtxt,
                 vs: &[ast::variant],
-                id: ast::NodeId)
+                id: ast::NodeId,
+                hint: attr::ReprAttr)
                 -> ~[@ty::VariantInfo] {
 
         let rty = ty::node_id_to_type(ccx.tcx, id);
@@ -3213,9 +3254,20 @@ fn do_check(ccx: @mut CrateCtxt,
                 None => ()
             };
 
-            // Check for duplicate discriminator values
+            // Check for duplicate discriminant values
             if disr_vals.contains(&current_disr_val) {
-                ccx.tcx.sess.span_err(v.span, "discriminator value already exists");
+                ccx.tcx.sess.span_err(v.span, "discriminant value already exists");
+            }
+            // Check for unrepresentable discriminant values
+            match hint {
+                attr::ReprAny | attr::ReprExtern => (),
+                attr::ReprInt(sp, ity) => {
+                    if !disr_in_range(ccx, ity, current_disr_val) {
+                        ccx.tcx.sess.span_err(v.span,
+                                              "discriminant value outside specified type");
+                        ccx.tcx.sess.span_note(sp, "discriminant type specified here");
+                    }
+                }
             }
             disr_vals.push(current_disr_val);
 
@@ -3229,8 +3281,13 @@ fn do_check(ccx: @mut CrateCtxt,
     }
 
     let rty = ty::node_id_to_type(ccx.tcx, id);
+    let hint = ty::lookup_repr_hint(ccx.tcx, ast::DefId { crate: ast::LOCAL_CRATE, node: id });
+    if hint != attr::ReprAny && vs.len() <= 1 {
+        ccx.tcx.sess.span_err(sp, format!("unsupported representation for {}variant enum",
+                                          if vs.len() == 1 { "uni" } else { "zero-" }))
+    }
 
-    let variants = do_check(ccx, vs, id);
+    let variants = do_check(ccx, vs, id, hint);
 
     // cache so that ty::enum_variants won't repeat this work
     ccx.tcx.enum_var_cache.insert(local_def(id), @variants);
index f483cfb0c658d23610b8bfdfe5659dd5f534f0b3..9119d1fb4e39374d307b9e12b57d824a4a4e1295 100644 (file)
@@ -232,15 +232,14 @@ fn drop_watcher_data(&mut self) {
         }
     }
 
-    fn close(self, cb: NullCallback) {
-        let mut this = self;
+    fn close(mut self, cb: NullCallback) {
         {
-            let data = this.get_watcher_data();
+            let data = self.get_watcher_data();
             assert!(data.close_cb.is_none());
             data.close_cb = Some(cb);
         }
 
-        unsafe { uvll::close(this.native_handle(), close_cb); }
+        unsafe { uvll::close(self.native_handle(), close_cb); }
 
         extern fn close_cb(handle: *uvll::uv_handle_t) {
             let mut h: Handle = NativeHandle::from_native_handle(handle);
index 8b80a24a1b48f6ec2f29f3ccf0fcaca8a4a6b7ee..8ea3e2ddcc67a8c0205fb4d2617f063bdae6a756 100644 (file)
@@ -122,10 +122,9 @@ fn home_for_io<A>(&mut self, io: &fn(&mut Self) -> A) -> A {
         a // return the result of the IO
     }
 
-    fn home_for_io_consume<A>(self, io: &fn(Self) -> A) -> A {
-        let mut this = self;
-        let home = this.go_to_IO_home();
-        let a = io(this); // do IO
+    fn home_for_io_consume<A>(mut self, io: &fn(Self) -> A) -> A {
+        let home = self.go_to_IO_home();
+        let a = io(self); // do IO
         HomingIO::restore_original_home(None::<Self>, home);
         a // return the result of the IO
     }
@@ -239,7 +238,7 @@ fn io<'a>(&'a mut self, f: &fn(&'a mut IoFactory)) {
     }
 }
 
-#[cfg(not(stage0), not(test))]
+#[cfg(not(test))]
 #[lang = "event_loop_factory"]
 pub extern "C" fn new_loop() -> ~EventLoop {
     ~UvEventLoop::new() as ~EventLoop
index 6f788e69cc93e523c78cc6b0a0bd5719ac10f29d..038598a29b8d479c3d28dc09a1591f00fe542d2b 100644 (file)
@@ -193,7 +193,7 @@ fn try_send_deferred(&self, val: T) -> bool {
     }
 }
 
-impl<T> Clone for SharedChan<T> {
+impl<T: Send> Clone for SharedChan<T> {
     fn clone(&self) -> SharedChan<T> {
         let &SharedChan { x: ref c } = self;
         SharedChan { x: c.clone() }
@@ -221,7 +221,7 @@ fn try_recv(&self) -> Option<T> {
     }
 }
 
-impl<T> Clone for SharedPort<T> {
+impl<T: Send> Clone for SharedPort<T> {
     fn clone(&self) -> SharedPort<T> {
         let &SharedPort { x: ref p } = self;
         SharedPort { x: p.clone() }
index 694e5e7f6bfee28153aa4631d292396a6dc8706a..ba1a7a4f912b8c6ea38dec45ab1b0cddd81414bb 100644 (file)
@@ -29,7 +29,8 @@ macro_rules! int_module (($T:ty, $bits:expr) => (mod generated {
 pub static bytes : uint = ($bits / 8);
 
 pub static min_value: $T = (-1 as $T) << (bits - 1);
-pub static max_value: $T = min_value - 1 as $T;
+// FIXME(#9837): Compute min_value like this so the high bits that shouldn't exist are 0.
+pub static max_value: $T = !min_value;
 
 impl CheckedDiv for $T {
     #[inline]
index d63b14f982d403a6dd845a2afc0555a6fcd84a85..19fa9abc0da55013e539ee3475b1bd39f60aef80 100644 (file)
@@ -16,7 +16,7 @@
 
 #[allow(missing_doc)];
 
-use unstable::intrinsics::{Opaque, TyDesc, TyVisitor};
+use unstable::intrinsics::{Disr, Opaque, TyDesc, TyVisitor};
 use libc::c_void;
 use mem;
 use unstable::raw;
@@ -396,7 +396,7 @@ fn visit_leave_fn(&mut self, purity: uint, proto: uint,
     }
 
     fn visit_enter_enum(&mut self, n_variants: uint,
-                        get_disr: extern unsafe fn(ptr: *Opaque) -> int,
+                        get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
                         sz: uint, align: uint)
                      -> bool {
         self.align(align);
@@ -407,7 +407,7 @@ fn visit_enter_enum(&mut self, n_variants: uint,
     }
 
     fn visit_enter_enum_variant(&mut self, variant: uint,
-                                disr_val: int,
+                                disr_val: Disr,
                                 n_fields: uint,
                                 name: &str) -> bool {
         if ! self.inner.visit_enter_enum_variant(variant, disr_val,
@@ -426,7 +426,7 @@ fn visit_enum_variant_field(&mut self, i: uint, offset: uint, inner: *TyDesc) ->
     }
 
     fn visit_leave_enum_variant(&mut self, variant: uint,
-                                disr_val: int,
+                                disr_val: Disr,
                                 n_fields: uint,
                                 name: &str) -> bool {
         if ! self.inner.visit_leave_enum_variant(variant, disr_val,
@@ -437,7 +437,7 @@ fn visit_leave_enum_variant(&mut self, variant: uint,
     }
 
     fn visit_leave_enum(&mut self, n_variants: uint,
-                        get_disr: extern unsafe fn(ptr: *Opaque) -> int,
+                        get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
                         sz: uint, align: uint) -> bool {
         if ! self.inner.visit_leave_enum(n_variants, get_disr, sz, align) {
             return false;
index d03621eb60d2f216aee918d48808512fe2d63edf..dd68c57e37e9763f896ca75a10a7827aad31c9c2 100644 (file)
@@ -29,7 +29,7 @@
 use str::StrSlice;
 use to_str::ToStr;
 use vec::OwnedVector;
-use unstable::intrinsics::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
+use unstable::intrinsics::{Disr, Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
 use unstable::raw;
 
 /// Representations
@@ -92,7 +92,7 @@ fn write_repr(&self, writer: &mut io::Writer) {
 // New implementation using reflect::MovePtr
 
 enum VariantState {
-    SearchingFor(int),
+    SearchingFor(Disr),
     Matched,
     AlreadyFound
 }
@@ -473,7 +473,7 @@ fn visit_leave_tup(&mut self, _n_fields: uint,
 
     fn visit_enter_enum(&mut self,
                         _n_variants: uint,
-                        get_disr: extern unsafe fn(ptr: *Opaque) -> int,
+                        get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
                         _sz: uint,
                         _align: uint) -> bool {
         let disr = unsafe {
@@ -484,7 +484,7 @@ fn visit_enter_enum(&mut self,
     }
 
     fn visit_enter_enum_variant(&mut self, _variant: uint,
-                                disr_val: int,
+                                disr_val: Disr,
                                 n_fields: uint,
                                 name: &str) -> bool {
         let mut write = false;
@@ -531,7 +531,7 @@ fn visit_enum_variant_field(&mut self,
     }
 
     fn visit_leave_enum_variant(&mut self, _variant: uint,
-                                _disr_val: int,
+                                _disr_val: Disr,
                                 n_fields: uint,
                                 _name: &str) -> bool {
         match self.var_stk[self.var_stk.len() - 1] {
@@ -547,7 +547,7 @@ fn visit_leave_enum_variant(&mut self, _variant: uint,
 
     fn visit_leave_enum(&mut self,
                         _n_variants: uint,
-                        _get_disr: extern unsafe fn(ptr: *Opaque) -> int,
+                        _get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
                         _sz: uint,
                         _align: uint)
                         -> bool {
index 7fcd674009d88e9fe9a8807bc53493ac5eaf9252..bd528cbe61f06ce012654c5c49229fa3959dcde5 100644 (file)
@@ -65,7 +65,7 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) ->
         None => { // not recording borrows
             let msg = "borrowed";
             do msg.with_c_str |msg_p| {
-                task::begin_unwind(msg_p, file, line);
+                task::begin_unwind_raw(msg_p, file, line);
             }
         }
         Some(borrow_list) => { // recording borrows
@@ -81,7 +81,7 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) ->
                 }
             }
             do msg.with_c_str |msg_p| {
-                task::begin_unwind(msg_p, file, line)
+                task::begin_unwind_raw(msg_p, file, line)
             }
         }
     }
@@ -180,7 +180,7 @@ pub unsafe fn unrecord_borrow(a: *u8, old_ref_count: uint,
             if br.box != a || br.file != file || br.line != line {
                 let err = format!("wrong borrow found, br={:?}", br);
                 do err.with_c_str |msg_p| {
-                    task::begin_unwind(msg_p, file, line)
+                    task::begin_unwind_raw(msg_p, file, line)
                 }
             }
             borrow_list
index 42bd88345993a582e366596d66674d8a84adb0e2..3089ae2c2d0cefe80be28d1f5b9ec50b5f05e1ee 100644 (file)
@@ -78,7 +78,7 @@ pub fn oneshot<T: Send>() -> (PortOne<T>, ChanOne<T>) {
     }
 }
 
-impl<T> ChanOne<T> {
+impl<T: Send> ChanOne<T> {
     #[inline]
     fn packet(&self) -> *mut Packet<T> {
         unsafe {
@@ -181,7 +181,7 @@ fn try_send_inner(mut self, val: T, do_resched: bool) -> bool {
     }
 }
 
-impl<T> PortOne<T> {
+impl<T: Send> PortOne<T> {
     fn packet(&self) -> *mut Packet<T> {
         unsafe {
             let p: *mut ~Packet<T> = cast::transmute(&self.void_packet);
@@ -218,7 +218,7 @@ pub fn try_recv(mut self) -> Option<T> {
     }
 }
 
-impl<T> SelectInner for PortOne<T> {
+impl<T: Send> SelectInner for PortOne<T> {
     #[inline] #[cfg(not(test))]
     fn optimistic_check(&mut self) -> bool {
         unsafe { (*self.packet()).state.load(Acquire) == STATE_ONE }
@@ -319,9 +319,9 @@ fn unblock_from(&mut self) -> bool {
     }
 }
 
-impl<T> Select for PortOne<T> { }
+impl<T: Send> Select for PortOne<T> { }
 
-impl<T> SelectPortInner<T> for PortOne<T> {
+impl<T: Send> SelectPortInner<T> for PortOne<T> {
     fn recv_ready(mut self) -> Option<T> {
         let packet = self.packet();
 
@@ -352,9 +352,9 @@ fn recv_ready(mut self) -> Option<T> {
     }
 }
 
-impl<T> SelectPort<T> for PortOne<T> { }
+impl<T: Send> SelectPort<T> for PortOne<T> { }
 
-impl<T> Peekable<T> for PortOne<T> {
+impl<T: Send> Peekable<T> for PortOne<T> {
     fn peek(&self) -> bool {
         unsafe {
             let packet: *mut Packet<T> = self.packet();
@@ -369,7 +369,7 @@ fn peek(&self) -> bool {
 }
 
 #[unsafe_destructor]
-impl<T> Drop for ChanOne<T> {
+impl<T: Send> Drop for ChanOne<T> {
     fn drop(&mut self) {
         if self.suppress_finalize { return }
 
@@ -396,7 +396,7 @@ fn drop(&mut self) {
 }
 
 #[unsafe_destructor]
-impl<T> Drop for PortOne<T> {
+impl<T: Send> Drop for PortOne<T> {
     fn drop(&mut self) {
         if self.suppress_finalize { return }
 
@@ -478,7 +478,7 @@ fn try_send_deferred(&self, val: T) -> bool {
     }
 }
 
-impl<T> GenericPort<T> for Port<T> {
+impl<T: Send> GenericPort<T> for Port<T> {
     fn recv(&self) -> T {
         match self.try_recv() {
             Some(val) => val,
@@ -501,7 +501,7 @@ fn try_recv(&self) -> Option<T> {
     }
 }
 
-impl<T> Peekable<T> for Port<T> {
+impl<T: Send> Peekable<T> for Port<T> {
     fn peek(&self) -> bool {
         self.next.with_mut_ref(|p| p.peek())
     }
@@ -511,7 +511,7 @@ fn peek(&self) -> bool {
 // of them, but a &Port<T> should also be selectable so you can select2 on it
 // alongside a PortOne<U> without passing the port by value in recv_ready.
 
-impl<'self, T> SelectInner for &'self Port<T> {
+impl<'self, T: Send> SelectInner for &'self Port<T> {
     #[inline]
     fn optimistic_check(&mut self) -> bool {
         do self.next.with_mut_ref |pone| { pone.optimistic_check() }
@@ -529,9 +529,9 @@ fn unblock_from(&mut self) -> bool {
     }
 }
 
-impl<'self, T> Select for &'self Port<T> { }
+impl<'self, T: Send> Select for &'self Port<T> { }
 
-impl<T> SelectInner for Port<T> {
+impl<T: Send> SelectInner for Port<T> {
     #[inline]
     fn optimistic_check(&mut self) -> bool {
         (&*self).optimistic_check()
@@ -548,9 +548,9 @@ fn unblock_from(&mut self) -> bool {
     }
 }
 
-impl<T> Select for Port<T> { }
+impl<T: Send> Select for Port<T> { }
 
-impl<'self, T> SelectPortInner<T> for &'self Port<T> {
+impl<'self, T: Send> SelectPortInner<T> for &'self Port<T> {
     fn recv_ready(self) -> Option<T> {
         match self.next.take().recv_ready() {
             Some(StreamPayload { val, next }) => {
@@ -562,14 +562,14 @@ fn recv_ready(self) -> Option<T> {
     }
 }
 
-impl<'self, T> SelectPort<T> for &'self Port<T> { }
+impl<'self, T: Send> SelectPort<T> for &'self Port<T> { }
 
 pub struct SharedChan<T> {
     // Just like Chan, but a shared AtomicOption instead of Cell
     priv next: UnsafeArc<AtomicOption<StreamChanOne<T>>>
 }
 
-impl<T> SharedChan<T> {
+impl<T: Send> SharedChan<T> {
     pub fn new(chan: Chan<T>) -> SharedChan<T> {
         let next = chan.next.take();
         let next = AtomicOption::new(~next);
@@ -609,7 +609,7 @@ fn try_send_deferred(&self, val: T) -> bool {
     }
 }
 
-impl<T> Clone for SharedChan<T> {
+impl<T: Send> Clone for SharedChan<T> {
     fn clone(&self) -> SharedChan<T> {
         SharedChan {
             next: self.next.clone()
@@ -622,7 +622,7 @@ pub struct SharedPort<T> {
     priv next_link: UnsafeArc<AtomicOption<PortOne<StreamPortOne<T>>>>
 }
 
-impl<T> SharedPort<T> {
+impl<T: Send> SharedPort<T> {
     pub fn new(port: Port<T>) -> SharedPort<T> {
         // Put the data port into a new link pipe
         let next_data_port = port.next.take();
@@ -664,7 +664,7 @@ fn try_recv(&self) -> Option<T> {
     }
 }
 
-impl<T> Clone for SharedPort<T> {
+impl<T: Send> Clone for SharedPort<T> {
     fn clone(&self) -> SharedPort<T> {
         SharedPort {
             next_link: self.next_link.clone()
index 16b41276788a00e3515a6610557341194c6237d4..a7a5b0084a275681e4271659f6d68b6e0e577270 100644 (file)
@@ -12,7 +12,6 @@
 use hashmap::HashSet;
 use option::{Some, None, Option};
 use vec::ImmutableVector;
-#[cfg(not(stage0))]
 use rt::rtio::EventLoop;
 
 // Need to tell the linker on OS X to not barf on undefined symbols
@@ -27,14 +26,6 @@ pub struct ModEntry<'self> {
     log_level: *mut u32
 }
 
-#[cfg(stage0)]
-pub struct CrateMap<'self> {
-    version: i32,
-    entries: &'self [ModEntry<'self>],
-    children: &'self [&'self CrateMap<'self>]
-}
-
-#[cfg(not(stage0))]
 pub struct CrateMap<'self> {
     version: i32,
     entries: &'self [ModEntry<'self>],
@@ -45,12 +36,6 @@ pub struct CrateMap<'self> {
 #[cfg(not(windows))]
 pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
     extern {
-        #[cfg(stage0)]
-        #[weak_linkage]
-        #[link_name = "_rust_crate_map_toplevel"]
-        static CRATE_MAP: CrateMap<'static>;
-
-        #[cfg(not(stage0))]
         #[crate_map]
         static CRATE_MAP: CrateMap<'static>;
     }
index 4c6c675df0342c1faecdb3a91de264be5622a718..b782d713950d90c36e70ec31a37f08cdaa07d029 100644 (file)
@@ -26,6 +26,7 @@
 use rt::io::io_error;
 use rt::rtio::{IoFactory, RtioSignal, with_local_io};
 
+#[repr(int)]
 #[deriving(Eq, IterBytes)]
 pub enum Signum {
     /// Equivalent to SIGBREAK, delivered when the user presses Ctrl-Break.
index edf6ffb820b31f1615a2c1763c0438b7329331b8..949421db9fc808a48fa3a93cde76fe68dc6c51f9 100644 (file)
@@ -155,7 +155,7 @@ fn test_something_in_another_task {
 use option::{Option, Some, None};
 use prelude::*;
 use rt::task::Task;
-use rt::task::UnwindReasonLinked;
+use rt::task::UnwindMessageLinked;
 use rt::task::{UnwindResult, Failure};
 use task::spawn::Taskgroup;
 use to_bytes::IterBytes;
@@ -597,7 +597,7 @@ pub fn collect_failure(&mut self, result: UnwindResult, group: Option<Taskgroup>
                 }
 
                 if !success {
-                    result = Cell::new(Failure(UnwindReasonLinked));
+                    result = Cell::new(Failure(UnwindMessageLinked));
                 }
             }
             on_exit(result.take());
index d8d07f140217dc968d02208aeb071b61edeeb159..a247b4afb80caf692885fbf4d018314c2c14464a 100644 (file)
@@ -121,10 +121,6 @@ pub mod shouldnt_be_public {
 /// The EventLoop and internal synchronous I/O interface.
 pub mod rtio;
 
-/// libuv and default rtio implementation.
-#[cfg(stage0)]
-pub mod uv;
-
 /// The Local trait for types that are accessible via thread-local
 /// or task-local storage.
 pub mod local;
@@ -463,13 +459,6 @@ pub fn in_green_task_context() -> bool {
     }
 }
 
-#[cfg(stage0)]
-pub fn new_event_loop() -> ~rtio::EventLoop {
-    use rt::uv::uvio::UvEventLoop;
-    ~UvEventLoop::new() as ~rtio::EventLoop
-}
-
-#[cfg(not(stage0))]
 pub fn new_event_loop() -> ~rtio::EventLoop {
     #[fixed_stack_segment]; #[allow(cstack)];
 
index 516a795a1adf10aa922781fa9cd4d450c6337049..b56dd0809dfd102e7980d07b7d58178d77232e24 100644 (file)
@@ -95,8 +95,8 @@ pub enum UnwindResult {
     /// The task is ending successfully
     Success,
 
-    /// The Task is failing with reason `UnwindReason`
-    Failure(UnwindReason),
+    /// The Task is failing with reason `UnwindMessage`
+    Failure(UnwindMessage),
 }
 
 impl UnwindResult {
@@ -121,20 +121,25 @@ pub fn is_success(&self) -> bool {
 
 /// Represents the cause of a task failure
 #[deriving(ToStr)]
-pub enum UnwindReason {
-    /// Failed with a string message
-    UnwindReasonStr(SendStr),
+pub enum UnwindMessage {
+    // FIXME: #9913 - This variant is not neccessary once Any works properly
+    /// Failed with a static string message
+    UnwindMessageStrStatic(&'static str),
+
+    // FIXME: #9913 - This variant is not neccessary once Any works properly
+    /// Failed with a owned string message
+    UnwindMessageStrOwned(~str),
 
     /// Failed with an `~Any`
-    UnwindReasonAny(~Any),
+    UnwindMessageAny(~Any),
 
     /// Failed because of linked failure
-    UnwindReasonLinked
+    UnwindMessageLinked
 }
 
 pub struct Unwinder {
     unwinding: bool,
-    cause: Option<UnwindReason>
+    cause: Option<UnwindMessage>
 }
 
 impl Unwinder {
@@ -527,7 +532,7 @@ fn rust_try(f: extern "C" fn(*c_void, *c_void),
         }
     }
 
-    pub fn begin_unwind(&mut self, cause: UnwindReason) -> ! {
+    pub fn begin_unwind(&mut self, cause: UnwindMessage) -> ! {
         #[fixed_stack_segment]; #[inline(never)];
 
         self.unwinding = true;
@@ -622,7 +627,7 @@ pub extern "C" fn rust_stack_exhausted() {
 /// This is the entry point of unwinding for things like lang items and such.
 /// The arguments are normally generated by the compiler, and need to
 /// have static lifetimes.
-pub fn begin_unwind(msg: *c_char, file: *c_char, line: size_t) -> ! {
+pub fn begin_unwind_raw(msg: *c_char, file: *c_char, line: size_t) -> ! {
     use c_str::CString;
     use cast::transmute;
 
@@ -638,11 +643,33 @@ fn static_char_ptr(p: *c_char) -> &'static str {
     let msg = static_char_ptr(msg);
     let file = static_char_ptr(file);
 
-    begin_unwind_reason(UnwindReasonStr(msg.into_send_str()), file, line as uint)
+    begin_unwind(msg, file, line as uint)
 }
 
 /// This is the entry point of unwinding for fail!() and assert!().
-pub fn begin_unwind_reason(reason: UnwindReason, file: &'static str, line: uint) -> ! {
+pub fn begin_unwind<M: Any + Send>(msg: M, file: &'static str, line: uint) -> ! {
+    // Wrap the fail message in a `Any` box for uniform representation.
+    let any = ~msg as ~Any;
+
+    // FIXME: #9913 - This can be changed to be internal to begin_unwind_internal
+    // once Any works properly.
+    // As a workaround, string types need to be special cased right now
+    // because `Any` does not support dynamically querying whether the
+    // type implements a trait yet, so without requiring that every `Any`
+    // also implements `ToStr` there is no way to get a failure message
+    // out of it again during unwinding.
+    let msg = if any.is::<&'static str>() {
+        UnwindMessageStrStatic(*any.move::<&'static str>().unwrap())
+    } else if any.is::<~str>() {
+        UnwindMessageStrOwned(*any.move::<~str>().unwrap())
+    } else {
+        UnwindMessageAny(any)
+    };
+
+    begin_unwind_internal(msg, file, line)
+}
+
+fn begin_unwind_internal(msg: UnwindMessage, file: &'static str, line: uint) -> ! {
     use rt::in_green_task_context;
     use rt::task::Task;
     use rt::local::Local;
@@ -656,15 +683,16 @@ pub fn begin_unwind_reason(reason: UnwindReason, file: &'static str, line: uint)
         let task: *mut Task;
 
         {
-            let msg = match reason {
-                UnwindReasonStr(ref s) => s.as_slice(),
-                UnwindReasonAny(_)     => "~Any",
-                UnwindReasonLinked     => "linked failure",
+            let msg_s = match msg {
+                UnwindMessageAny(_) => "~Any",
+                UnwindMessageLinked => "linked failure",
+                UnwindMessageStrOwned(ref s)  => s.as_slice(),
+                UnwindMessageStrStatic(ref s) => s.as_slice(),
             };
 
             if !in_green_task_context() {
                 rterrln!("failed in non-task context at '{}', {}:{}",
-                        msg, file, line);
+                         msg_s, file, line);
                 intrinsics::abort();
             }
 
@@ -679,19 +707,20 @@ pub fn begin_unwind_reason(reason: UnwindReason, file: &'static str, line: uint)
             //      due to mismanagment of its own kill flag, so calling our own
             //      logger in its current state is a bit of a problem.
 
-            rterrln!("task '{}' failed at '{}', {}:{}", n, msg, file, line);
+            rterrln!("task '{}' failed at '{}', {}:{}", n, msg_s, file, line);
 
             if (*task).unwinder.unwinding {
                 rtabort!("unwinding again");
             }
         }
 
-        (*task).unwinder.begin_unwind(reason);
+        (*task).unwinder.begin_unwind(msg);
     }
 }
 
 #[cfg(test)]
 mod test {
+    use super::*;
     use rt::test::*;
 
     #[test]
@@ -804,4 +833,8 @@ struct List {
             a.next = Some(b);
         }
     }
+
+    #[test]
+    #[should_fail]
+    fn test_begin_unwind() { begin_unwind("cause", file!(), line!()) }
 }
diff --git a/src/libstd/rt/uv/addrinfo.rs b/src/libstd/rt/uv/addrinfo.rs
deleted file mode 100644 (file)
index a1593d5..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-// Copyright 2013 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 cast::transmute;
-use cell::Cell;
-use c_str::ToCStr;
-use libc::{c_int, c_void};
-use option::{Option, Some, None};
-use ptr::null;
-use rt::uv::uvll;
-use rt::uv::uvll::UV_GETADDRINFO;
-use rt::uv::{Loop, UvError, NativeHandle};
-use rt::uv::status_to_maybe_uv_error;
-use rt::uv::net;
-use ai = rt::io::net::addrinfo;
-
-type GetAddrInfoCallback = ~fn(GetAddrInfoRequest, &net::UvAddrInfo, Option<UvError>);
-
-pub struct GetAddrInfoRequest(*uvll::uv_getaddrinfo_t);
-
-pub struct RequestData {
-    priv getaddrinfo_cb: Option<GetAddrInfoCallback>,
-}
-
-impl GetAddrInfoRequest {
-    pub fn new() -> GetAddrInfoRequest {
-        let req = unsafe { uvll::malloc_req(UV_GETADDRINFO) };
-        assert!(req.is_not_null());
-        let mut req: GetAddrInfoRequest = NativeHandle::from_native_handle(req);
-        req.install_req_data();
-        return req;
-    }
-
-    pub fn getaddrinfo(&mut self, loop_: &Loop, node: Option<&str>,
-                       service: Option<&str>, hints: Option<ai::Hint>,
-                       cb: GetAddrInfoCallback) {
-
-        assert!(node.is_some() || service.is_some());
-
-        let (c_node, c_node_ptr) = match node {
-            Some(n) => {
-                let c_node = n.to_c_str();
-                let c_node_ptr = c_node.with_ref(|r| r);
-                (Some(c_node), c_node_ptr)
-            }
-            None => (None, null())
-        };
-
-        let (c_service, c_service_ptr) = match service {
-            Some(s) => {
-                let c_service = s.to_c_str();
-                let c_service_ptr = c_service.with_ref(|r| r);
-                (Some(c_service), c_service_ptr)
-            }
-            None => (None, null())
-        };
-
-        let cb = Cell::new(cb);
-        let wrapper_cb: GetAddrInfoCallback = |req, addrinfo, err| {
-            // Capture some heap values that need to stay alive for the
-            // getaddrinfo call
-            let _ = &c_node;
-            let _ = &c_service;
-
-            let cb = cb.take();
-            cb(req, addrinfo, err)
-        };
-
-        let hint = hints.map(|hint| {
-            let mut flags = 0;
-            do each_ai_flag |cval, aival| {
-                if hint.flags & (aival as uint) != 0 {
-                    flags |= cval as i32;
-                }
-            }
-            /* XXX: do we really want to support these?
-            let socktype = match hint.socktype {
-                Some(ai::Stream) => uvll::rust_SOCK_STREAM(),
-                Some(ai::Datagram) => uvll::rust_SOCK_DGRAM(),
-                Some(ai::Raw) => uvll::rust_SOCK_RAW(),
-                None => 0,
-            };
-            let protocol = match hint.protocol {
-                Some(ai::UDP) => uvll::rust_IPPROTO_UDP(),
-                Some(ai::TCP) => uvll::rust_IPPROTO_TCP(),
-                _ => 0,
-            };
-            */
-            let socktype = 0;
-            let protocol = 0;
-
-            uvll::addrinfo {
-                ai_flags: flags,
-                ai_family: hint.family as c_int,
-                ai_socktype: socktype,
-                ai_protocol: protocol,
-                ai_addrlen: 0,
-                ai_canonname: null(),
-                ai_addr: null(),
-                ai_next: null(),
-            }
-        });
-        let hint_ptr = hint.as_ref().map_default(null(), |x| x as *uvll::addrinfo);
-
-        self.get_req_data().getaddrinfo_cb = Some(wrapper_cb);
-
-        unsafe {
-            assert!(0 == uvll::getaddrinfo(loop_.native_handle(),
-                                           self.native_handle(),
-                                           getaddrinfo_cb,
-                                           c_node_ptr,
-                                           c_service_ptr,
-                                           hint_ptr));
-        }
-
-        extern "C" fn getaddrinfo_cb(req: *uvll::uv_getaddrinfo_t,
-                                     status: c_int,
-                                     res: *uvll::addrinfo) {
-            let mut req: GetAddrInfoRequest = NativeHandle::from_native_handle(req);
-            let err = status_to_maybe_uv_error(status);
-            let addrinfo = net::UvAddrInfo(res);
-            let data = req.get_req_data();
-            (*data.getaddrinfo_cb.get_ref())(req, &addrinfo, err);
-            unsafe {
-                uvll::freeaddrinfo(res);
-            }
-        }
-    }
-
-    fn get_loop(&self) -> Loop {
-        unsafe {
-            Loop {
-                handle: uvll::get_loop_from_fs_req(self.native_handle())
-            }
-        }
-    }
-
-    fn install_req_data(&mut self) {
-        let req = self.native_handle() as *uvll::uv_getaddrinfo_t;
-        let data = ~RequestData {
-            getaddrinfo_cb: None
-        };
-        unsafe {
-            let data = transmute::<~RequestData, *c_void>(data);
-            uvll::set_data_for_req(req, data);
-        }
-    }
-
-    fn get_req_data<'r>(&'r mut self) -> &'r mut RequestData {
-        unsafe {
-            let data = uvll::get_data_for_req(self.native_handle());
-            let data = transmute::<&*c_void, &mut ~RequestData>(&data);
-            return &mut **data;
-        }
-    }
-
-    fn delete(self) {
-        unsafe {
-            let data = uvll::get_data_for_req(self.native_handle());
-            let _data = transmute::<*c_void, ~RequestData>(data);
-            uvll::set_data_for_req(self.native_handle(), null::<()>());
-            uvll::free_req(self.native_handle());
-        }
-    }
-}
-
-fn each_ai_flag(_f: &fn(c_int, ai::Flag)) {
-    /* XXX: do we really want to support these?
-    unsafe {
-        f(uvll::rust_AI_ADDRCONFIG(), ai::AddrConfig);
-        f(uvll::rust_AI_ALL(), ai::All);
-        f(uvll::rust_AI_CANONNAME(), ai::CanonName);
-        f(uvll::rust_AI_NUMERICHOST(), ai::NumericHost);
-        f(uvll::rust_AI_NUMERICSERV(), ai::NumericServ);
-        f(uvll::rust_AI_PASSIVE(), ai::Passive);
-        f(uvll::rust_AI_V4MAPPED(), ai::V4Mapped);
-    }
-    */
-}
-
-// Traverse the addrinfo linked list, producing a vector of Rust socket addresses
-pub fn accum_addrinfo(addr: &net::UvAddrInfo) -> ~[ai::Info] {
-    unsafe {
-        let &net::UvAddrInfo(addr) = addr;
-        let mut addr = addr;
-
-        let mut addrs = ~[];
-        loop {
-            let uvaddr = net::sockaddr_to_UvSocketAddr((*addr).ai_addr);
-            let rustaddr = net::uv_socket_addr_to_socket_addr(uvaddr);
-
-            let mut flags = 0;
-            do each_ai_flag |cval, aival| {
-                if (*addr).ai_flags & cval != 0 {
-                    flags |= aival as uint;
-                }
-            }
-
-            /* XXX: do we really want to support these
-            let protocol = match (*addr).ai_protocol {
-                p if p == uvll::rust_IPPROTO_UDP() => Some(ai::UDP),
-                p if p == uvll::rust_IPPROTO_TCP() => Some(ai::TCP),
-                _ => None,
-            };
-            let socktype = match (*addr).ai_socktype {
-                p if p == uvll::rust_SOCK_STREAM() => Some(ai::Stream),
-                p if p == uvll::rust_SOCK_DGRAM() => Some(ai::Datagram),
-                p if p == uvll::rust_SOCK_RAW() => Some(ai::Raw),
-                _ => None,
-            };
-            */
-            let protocol = None;
-            let socktype = None;
-
-            addrs.push(ai::Info {
-                address: rustaddr,
-                family: (*addr).ai_family as uint,
-                socktype: socktype,
-                protocol: protocol,
-                flags: flags,
-            });
-            if (*addr).ai_next.is_not_null() {
-                addr = (*addr).ai_next;
-            } else {
-                break;
-            }
-        }
-
-        return addrs;
-    }
-}
-
-impl NativeHandle<*uvll::uv_getaddrinfo_t> for GetAddrInfoRequest {
-    fn from_native_handle(handle: *uvll::uv_getaddrinfo_t) -> GetAddrInfoRequest {
-        GetAddrInfoRequest(handle)
-    }
-    fn native_handle(&self) -> *uvll::uv_getaddrinfo_t {
-        match self { &GetAddrInfoRequest(ptr) => ptr }
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use option::{Some, None};
-    use rt::uv::Loop;
-    use rt::io::net::ip::{SocketAddr, Ipv4Addr};
-    use super::*;
-
-    #[test]
-    fn getaddrinfo_test() {
-        let mut loop_ = Loop::new();
-        let mut req = GetAddrInfoRequest::new();
-        do req.getaddrinfo(&loop_, Some("localhost"), None, None) |_, addrinfo, _| {
-            let sockaddrs = accum_addrinfo(addrinfo);
-            let mut found_local = false;
-            let local_addr = &SocketAddr {
-                ip: Ipv4Addr(127, 0, 0, 1),
-                port: 0
-            };
-            for addr in sockaddrs.iter() {
-                found_local = found_local || addr.address == *local_addr;
-            }
-            assert!(found_local);
-        }
-        loop_.run();
-        loop_.close();
-        req.delete();
-    }
-}
diff --git a/src/libstd/rt/uv/async.rs b/src/libstd/rt/uv/async.rs
deleted file mode 100644 (file)
index 108aef4..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2013 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 libc::c_int;
-use option::Some;
-use rt::uv::uvll;
-use rt::uv::uvll::UV_ASYNC;
-use rt::uv::{Watcher, Loop, NativeHandle, AsyncCallback};
-use rt::uv::WatcherInterop;
-use rt::uv::status_to_maybe_uv_error;
-
-pub struct AsyncWatcher(*uvll::uv_async_t);
-impl Watcher for AsyncWatcher { }
-
-impl AsyncWatcher {
-    pub fn new(loop_: &mut Loop, cb: AsyncCallback) -> AsyncWatcher {
-        unsafe {
-            let handle = uvll::malloc_handle(UV_ASYNC);
-            assert!(handle.is_not_null());
-            let mut watcher: AsyncWatcher = NativeHandle::from_native_handle(handle);
-            watcher.install_watcher_data();
-            let data = watcher.get_watcher_data();
-            data.async_cb = Some(cb);
-            assert_eq!(0, uvll::async_init(loop_.native_handle(), handle, async_cb));
-            return watcher;
-        }
-
-        extern fn async_cb(handle: *uvll::uv_async_t, status: c_int) {
-            let mut watcher: AsyncWatcher = NativeHandle::from_native_handle(handle);
-            let status = status_to_maybe_uv_error(status);
-            let data = watcher.get_watcher_data();
-            let cb = data.async_cb.get_ref();
-            (*cb)(watcher, status);
-        }
-    }
-
-    pub fn send(&mut self) {
-        unsafe {
-            let handle = self.native_handle();
-            uvll::async_send(handle);
-        }
-    }
-}
-
-impl NativeHandle<*uvll::uv_async_t> for AsyncWatcher {
-    fn from_native_handle(handle: *uvll::uv_async_t) -> AsyncWatcher {
-        AsyncWatcher(handle)
-    }
-    fn native_handle(&self) -> *uvll::uv_async_t {
-        match self { &AsyncWatcher(ptr) => ptr }
-    }
-}
-
-#[cfg(test)]
-mod test {
-
-    use super::*;
-    use rt::uv::Loop;
-    use unstable::run_in_bare_thread;
-    use rt::thread::Thread;
-    use cell::Cell;
-
-    #[test]
-    fn smoke_test() {
-        do run_in_bare_thread {
-            let mut loop_ = Loop::new();
-            let watcher = AsyncWatcher::new(&mut loop_, |w, _| w.close(||()) );
-            let watcher_cell = Cell::new(watcher);
-            let thread = do Thread::start {
-                let mut watcher = watcher_cell.take();
-                watcher.send();
-            };
-            loop_.run();
-            loop_.close();
-            thread.join();
-        }
-    }
-}
diff --git a/src/libstd/rt/uv/file.rs b/src/libstd/rt/uv/file.rs
deleted file mode 100644 (file)
index d2ca159..0000000
+++ /dev/null
@@ -1,648 +0,0 @@
-// Copyright 2013 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 prelude::*;
-use ptr::null;
-use c_str;
-use c_str::CString;
-use libc::c_void;
-use rt::uv::{Request, NativeHandle, Loop, FsCallback, Buf,
-             status_to_maybe_uv_error, UvError};
-use rt::uv::uvll;
-use rt::uv::uvll::*;
-use cast::transmute;
-use libc;
-use libc::{c_int};
-use option::{None, Some, Option};
-
-pub struct FsRequest(*uvll::uv_fs_t);
-impl Request for FsRequest {}
-
-pub struct RequestData {
-    priv complete_cb: Option<FsCallback>
-}
-
-impl FsRequest {
-    pub fn new() -> FsRequest {
-        let fs_req = unsafe { malloc_req(UV_FS) };
-        assert!(fs_req.is_not_null());
-        let fs_req: FsRequest = NativeHandle::from_native_handle(fs_req);
-        fs_req
-    }
-
-    pub fn open(self, loop_: &Loop, path: &CString, flags: int, mode: int,
-                cb: FsCallback) {
-        let complete_cb_ptr = {
-            let mut me = self;
-            me.req_boilerplate(Some(cb))
-        };
-        let ret = path.with_ref(|p| unsafe {
-            uvll::fs_open(loop_.native_handle(),
-                          self.native_handle(), p, flags, mode, complete_cb_ptr)
-        });
-        assert_eq!(ret, 0);
-    }
-
-    pub fn open_sync(self, loop_: &Loop, path: &CString,
-                     flags: int, mode: int) -> Result<c_int, UvError> {
-        let complete_cb_ptr = {
-            let mut me = self;
-            me.req_boilerplate(None)
-        };
-        let result = path.with_ref(|p| unsafe {
-            uvll::fs_open(loop_.native_handle(),
-                    self.native_handle(), p, flags, mode, complete_cb_ptr)
-        });
-        self.sync_cleanup(result)
-    }
-
-    pub fn unlink(self, loop_: &Loop, path: &CString, cb: FsCallback) {
-        let complete_cb_ptr = {
-            let mut me = self;
-            me.req_boilerplate(Some(cb))
-        };
-        let ret = path.with_ref(|p| unsafe {
-            uvll::fs_unlink(loop_.native_handle(),
-                          self.native_handle(), p, complete_cb_ptr)
-        });
-        assert_eq!(ret, 0);
-    }
-
-    pub fn unlink_sync(self, loop_: &Loop, path: &CString)
-      -> Result<c_int, UvError> {
-        let complete_cb_ptr = {
-            let mut me = self;
-            me.req_boilerplate(None)
-        };
-        let result = path.with_ref(|p| unsafe {
-            uvll::fs_unlink(loop_.native_handle(),
-                          self.native_handle(), p, complete_cb_ptr)
-        });
-        self.sync_cleanup(result)
-    }
-
-    pub fn stat(self, loop_: &Loop, path: &CString, cb: FsCallback) {
-        let complete_cb_ptr = {
-            let mut me = self;
-            me.req_boilerplate(Some(cb))
-        };
-        let ret = path.with_ref(|p| unsafe {
-            uvll::fs_stat(loop_.native_handle(),
-                          self.native_handle(), p, complete_cb_ptr)
-        });
-        assert_eq!(ret, 0);
-    }
-
-    pub fn write(self, loop_: &Loop, fd: c_int, buf: Buf, offset: i64, cb: FsCallback) {
-        let complete_cb_ptr = {
-            let mut me = self;
-            me.req_boilerplate(Some(cb))
-        };
-        let base_ptr = buf.base as *c_void;
-        let len = buf.len as uint;
-        let ret = unsafe {
-            uvll::fs_write(loop_.native_handle(), self.native_handle(),
-                           fd, base_ptr,
-                           len, offset, complete_cb_ptr)
-        };
-        assert_eq!(ret, 0);
-    }
-    pub fn write_sync(self, loop_: &Loop, fd: c_int, buf: Buf, offset: i64)
-          -> Result<c_int, UvError> {
-        let complete_cb_ptr = {
-            let mut me = self;
-            me.req_boilerplate(None)
-        };
-        let base_ptr = buf.base as *c_void;
-        let len = buf.len as uint;
-        let result = unsafe {
-            uvll::fs_write(loop_.native_handle(), self.native_handle(),
-                           fd, base_ptr,
-                           len, offset, complete_cb_ptr)
-        };
-        self.sync_cleanup(result)
-    }
-
-    pub fn read(self, loop_: &Loop, fd: c_int, buf: Buf, offset: i64, cb: FsCallback) {
-        let complete_cb_ptr = {
-            let mut me = self;
-            me.req_boilerplate(Some(cb))
-        };
-        let buf_ptr = buf.base as *c_void;
-        let len = buf.len as uint;
-        let ret = unsafe {
-            uvll::fs_read(loop_.native_handle(), self.native_handle(),
-                           fd, buf_ptr,
-                           len, offset, complete_cb_ptr)
-        };
-        assert_eq!(ret, 0);
-    }
-    pub fn read_sync(self, loop_: &Loop, fd: c_int, buf: Buf, offset: i64)
-          -> Result<c_int, UvError> {
-        let complete_cb_ptr = {
-            let mut me = self;
-            me.req_boilerplate(None)
-        };
-        let buf_ptr = buf.base as *c_void;
-        let len = buf.len as uint;
-        let result = unsafe {
-            uvll::fs_read(loop_.native_handle(), self.native_handle(),
-                           fd, buf_ptr,
-                           len, offset, complete_cb_ptr)
-        };
-        self.sync_cleanup(result)
-    }
-
-    pub fn close(self, loop_: &Loop, fd: c_int, cb: FsCallback) {
-        let complete_cb_ptr = {
-            let mut me = self;
-            me.req_boilerplate(Some(cb))
-        };
-        let ret = unsafe {
-            uvll::fs_close(loop_.native_handle(), self.native_handle(),
-                           fd, complete_cb_ptr)
-        };
-        assert_eq!(ret, 0);
-    }
-    pub fn close_sync(self, loop_: &Loop, fd: c_int) -> Result<c_int, UvError> {
-        let complete_cb_ptr = {
-            let mut me = self;
-            me.req_boilerplate(None)
-        };
-        let result = unsafe {
-            uvll::fs_close(loop_.native_handle(), self.native_handle(),
-                           fd, complete_cb_ptr)
-        };
-        self.sync_cleanup(result)
-    }
-
-    pub fn mkdir(self, loop_: &Loop, path: &CString, mode: int, cb: FsCallback) {
-        let complete_cb_ptr = {
-            let mut me = self;
-            me.req_boilerplate(Some(cb))
-        };
-        let ret = path.with_ref(|p| unsafe {
-            uvll::fs_mkdir(loop_.native_handle(),
-                           self.native_handle(), p, mode, complete_cb_ptr)
-        });
-        assert_eq!(ret, 0);
-    }
-
-    pub fn rmdir(self, loop_: &Loop, path: &CString, cb: FsCallback) {
-        let complete_cb_ptr = {
-            let mut me = self;
-            me.req_boilerplate(Some(cb))
-        };
-        let ret = path.with_ref(|p| unsafe {
-            uvll::fs_rmdir(loop_.native_handle(),
-                           self.native_handle(), p, complete_cb_ptr)
-        });
-        assert_eq!(ret, 0);
-    }
-
-    pub fn readdir(self, loop_: &Loop, path: &CString,
-                   flags: c_int, cb: FsCallback) {
-        let complete_cb_ptr = {
-            let mut me = self;
-            me.req_boilerplate(Some(cb))
-        };
-        let ret = path.with_ref(|p| unsafe {
-            uvll::fs_readdir(loop_.native_handle(),
-                             self.native_handle(), p, flags, complete_cb_ptr)
-        });
-        assert_eq!(ret, 0);
-    }
-
-    // accessors/utility funcs
-    fn sync_cleanup(self, result: c_int)
-          -> Result<c_int, UvError> {
-        self.cleanup_and_delete();
-        match status_to_maybe_uv_error(result as i32) {
-            Some(err) => Err(err),
-            None => Ok(result)
-        }
-    }
-    fn req_boilerplate(&mut self, cb: Option<FsCallback>) -> *u8 {
-        let result = match cb {
-            Some(_) => {
-                compl_cb as *u8
-            },
-            None => 0 as *u8
-        };
-        self.install_req_data(cb);
-        result
-    }
-    pub fn install_req_data(&mut self, cb: Option<FsCallback>) {
-        let fs_req = (self.native_handle()) as *uvll::uv_write_t;
-        let data = ~RequestData {
-            complete_cb: cb
-        };
-        unsafe {
-            let data = transmute::<~RequestData, *c_void>(data);
-            uvll::set_data_for_req(fs_req, data);
-        }
-    }
-
-    fn get_req_data<'r>(&'r mut self) -> &'r mut RequestData {
-        unsafe {
-            let data = uvll::get_data_for_req((self.native_handle()));
-            let data = transmute::<&*c_void, &mut ~RequestData>(&data);
-            &mut **data
-        }
-    }
-
-    pub fn get_result(&mut self) -> c_int {
-        unsafe {
-            uvll::get_result_from_fs_req(self.native_handle())
-        }
-    }
-
-    pub fn get_loop(&self) -> Loop {
-        unsafe { Loop{handle:uvll::get_loop_from_fs_req(self.native_handle())} }
-    }
-
-    pub fn get_stat(&self) -> uv_stat_t {
-        let stat = uv_stat_t::new();
-        unsafe { uvll::populate_stat(self.native_handle(), &stat); }
-        stat
-    }
-
-    pub fn get_ptr(&self) -> *libc::c_void {
-        unsafe {
-            uvll::get_ptr_from_fs_req(self.native_handle())
-        }
-    }
-
-    pub fn each_path(&mut self, f: &fn(&CString)) {
-        let ptr = self.get_ptr();
-        match self.get_result() {
-            n if (n <= 0) => {}
-            n => {
-                let n_len = n as uint;
-                // we pass in the len that uv tells us is there
-                // for the entries and we don't continue past that..
-                // it appears that sometimes the multistring isn't
-                // correctly delimited and we stray into garbage memory?
-                // in any case, passing Some(n_len) fixes it and ensures
-                // good results
-                unsafe {
-                    c_str::from_c_multistring(ptr as *libc::c_char,
-                                              Some(n_len), f);
-                }
-            }
-        }
-    }
-
-    fn cleanup_and_delete(self) {
-        unsafe {
-            let data = uvll::get_data_for_req(self.native_handle());
-            let _data = transmute::<*c_void, ~RequestData>(data);
-            uvll::set_data_for_req(self.native_handle(), null::<()>());
-            uvll::fs_req_cleanup(self.native_handle());
-            free_req(self.native_handle() as *c_void)
-        }
-    }
-}
-
-impl NativeHandle<*uvll::uv_fs_t> for FsRequest {
-    fn from_native_handle(handle: *uvll:: uv_fs_t) -> FsRequest {
-        FsRequest(handle)
-    }
-    fn native_handle(&self) -> *uvll::uv_fs_t {
-        match self { &FsRequest(ptr) => ptr }
-    }
-}
-
-fn sync_cleanup(result: int)
-    -> Result<int, UvError> {
-    match status_to_maybe_uv_error(result as i32) {
-        Some(err) => Err(err),
-        None => Ok(result)
-    }
-}
-
-extern fn compl_cb(req: *uv_fs_t) {
-    let mut req: FsRequest = NativeHandle::from_native_handle(req);
-    // pull the user cb out of the req data
-    let cb = {
-        let data = req.get_req_data();
-        assert!(data.complete_cb.is_some());
-        // option dance, option dance. oooooh yeah.
-        data.complete_cb.take_unwrap()
-    };
-    // in uv_fs_open calls, the result will be the fd in the
-    // case of success, otherwise it's -1 indicating an error
-    let result = req.get_result();
-    let status = status_to_maybe_uv_error(result);
-    // we have a req and status, call the user cb..
-    // only giving the user a ref to the FsRequest, as we
-    // have to clean it up, afterwards (and they aren't really
-    // reusable, anyways
-    cb(&mut req, status);
-    // clean up the req (and its data!) after calling the user cb
-    req.cleanup_and_delete();
-}
-
-#[cfg(test)]
-mod test {
-    use super::*;
-    //use rt::test::*;
-    use libc::{STDOUT_FILENO};
-    use vec;
-    use str;
-    use unstable::run_in_bare_thread;
-    use rt::uv::{Loop, Buf, slice_to_uv_buf};
-    use libc::{O_CREAT, O_RDWR, O_RDONLY, S_IWUSR, S_IRUSR};
-
-    #[test]
-    fn file_test_full_simple() {
-        do run_in_bare_thread {
-            let mut loop_ = Loop::new();
-            let create_flags = O_RDWR | O_CREAT;
-            let read_flags = O_RDONLY;
-            // 0644 BZZT! WRONG! 0600! See below.
-            let mode = S_IWUSR |S_IRUSR;
-                // these aren't defined in std::libc :(
-                //map_mode(S_IRGRP) |
-                //map_mode(S_IROTH);
-            let path_str = "./tmp/file_full_simple.txt";
-            let write_val = "hello".as_bytes().to_owned();
-            let write_buf  = slice_to_uv_buf(write_val);
-            let write_buf_ptr: *Buf = &write_buf;
-            let read_buf_len = 1028;
-            let read_mem = vec::from_elem(read_buf_len, 0u8);
-            let read_buf = slice_to_uv_buf(read_mem);
-            let read_buf_ptr: *Buf = &read_buf;
-            let open_req = FsRequest::new();
-            do open_req.open(&loop_, &path_str.to_c_str(), create_flags as int,
-                             mode as int) |req, uverr| {
-                assert!(uverr.is_none());
-                let fd = req.get_result();
-                let buf = unsafe { *write_buf_ptr };
-                let write_req = FsRequest::new();
-                do write_req.write(&req.get_loop(), fd, buf, -1) |req, uverr| {
-                    let close_req = FsRequest::new();
-                    do close_req.close(&req.get_loop(), fd) |req, _| {
-                        assert!(uverr.is_none());
-                        let loop_ = req.get_loop();
-                        let open_req = FsRequest::new();
-                        do open_req.open(&loop_, &path_str.to_c_str(),
-                                         read_flags as int,0) |req, uverr| {
-                            assert!(uverr.is_none());
-                            let loop_ = req.get_loop();
-                            let fd = req.get_result();
-                            let read_buf = unsafe { *read_buf_ptr };
-                            let read_req = FsRequest::new();
-                            do read_req.read(&loop_, fd, read_buf, 0) |req, uverr| {
-                                assert!(uverr.is_none());
-                                let loop_ = req.get_loop();
-                                // we know nread >=0 because uverr is none..
-                                let nread = req.get_result() as uint;
-                                // nread == 0 would be EOF
-                                if nread > 0 {
-                                    let read_str = unsafe {
-                                        let read_buf = *read_buf_ptr;
-                                        str::from_utf8(
-                                            vec::from_buf(
-                                                read_buf.base, nread))
-                                    };
-                                    assert!(read_str == ~"hello");
-                                    let close_req = FsRequest::new();
-                                    do close_req.close(&loop_, fd) |req,uverr| {
-                                        assert!(uverr.is_none());
-                                        let loop_ = &req.get_loop();
-                                        let unlink_req = FsRequest::new();
-                                        do unlink_req.unlink(loop_,
-                                                             &path_str.to_c_str())
-                                        |_,uverr| {
-                                            assert!(uverr.is_none());
-                                        };
-                                    };
-                                };
-                            };
-                        };
-                    };
-                };
-            };
-            loop_.run();
-            loop_.close();
-        }
-    }
-
-    #[test]
-    fn file_test_full_simple_sync() {
-        do run_in_bare_thread {
-            // setup
-            let mut loop_ = Loop::new();
-            let create_flags = O_RDWR |
-                O_CREAT;
-            let read_flags = O_RDONLY;
-            // 0644
-            let mode = S_IWUSR |
-                S_IRUSR;
-                //S_IRGRP |
-                //S_IROTH;
-            let path_str = "./tmp/file_full_simple_sync.txt";
-            let write_val = "hello".as_bytes().to_owned();
-            let write_buf = slice_to_uv_buf(write_val);
-            // open/create
-            let open_req = FsRequest::new();
-            let result = open_req.open_sync(&loop_, &path_str.to_c_str(),
-                                            create_flags as int, mode as int);
-            assert!(result.is_ok());
-            let fd = result.unwrap();
-            // write
-            let write_req = FsRequest::new();
-            let result = write_req.write_sync(&loop_, fd, write_buf, -1);
-            assert!(result.is_ok());
-            // close
-            let close_req = FsRequest::new();
-            let result = close_req.close_sync(&loop_, fd);
-            assert!(result.is_ok());
-            // re-open
-            let open_req = FsRequest::new();
-            let result = open_req.open_sync(&loop_, &path_str.to_c_str(),
-                                                   read_flags as int,0);
-            assert!(result.is_ok());
-            let len = 1028;
-            let fd = result.unwrap();
-            // read
-            let read_mem: ~[u8] = vec::from_elem(len, 0u8);
-            let buf = slice_to_uv_buf(read_mem);
-            let read_req = FsRequest::new();
-            let result = read_req.read_sync(&loop_, fd, buf, 0);
-            assert!(result.is_ok());
-            let nread = result.unwrap();
-            // nread == 0 would be EOF.. we know it's >= zero because otherwise
-            // the above assert would fail
-            if nread > 0 {
-                let read_str = str::from_utf8(
-                    read_mem.slice(0, nread as uint));
-                assert!(read_str == ~"hello");
-                // close
-                let close_req = FsRequest::new();
-                let result = close_req.close_sync(&loop_, fd);
-                assert!(result.is_ok());
-                // unlink
-                let unlink_req = FsRequest::new();
-                let result = unlink_req.unlink_sync(&loop_, &path_str.to_c_str());
-                assert!(result.is_ok());
-            } else { fail!("nread was 0.. wudn't expectin' that."); }
-            loop_.close();
-        }
-    }
-
-    fn naive_print(loop_: &Loop, input: &str) {
-        let write_val = input.as_bytes();
-        let write_buf = slice_to_uv_buf(write_val);
-        let write_req = FsRequest::new();
-        write_req.write_sync(loop_, STDOUT_FILENO, write_buf, -1);
-    }
-
-    #[test]
-    fn file_test_write_to_stdout() {
-        do run_in_bare_thread {
-            let mut loop_ = Loop::new();
-            naive_print(&loop_, "zanzibar!\n");
-            loop_.run();
-            loop_.close();
-        };
-    }
-    #[test]
-    fn file_test_stat_simple() {
-        do run_in_bare_thread {
-            let mut loop_ = Loop::new();
-            let path = "./tmp/file_test_stat_simple.txt";
-            let create_flags = O_RDWR |
-                O_CREAT;
-            let mode = S_IWUSR |
-                S_IRUSR;
-            let write_val = "hello".as_bytes().to_owned();
-            let write_buf  = slice_to_uv_buf(write_val);
-            let write_buf_ptr: *Buf = &write_buf;
-            let open_req = FsRequest::new();
-            do open_req.open(&loop_, &path.to_c_str(), create_flags as int,
-                             mode as int) |req, uverr| {
-                assert!(uverr.is_none());
-                let fd = req.get_result();
-                let buf = unsafe { *write_buf_ptr };
-                let write_req = FsRequest::new();
-                do write_req.write(&req.get_loop(), fd, buf, 0) |req, uverr| {
-                    assert!(uverr.is_none());
-                    let loop_ = req.get_loop();
-                    let stat_req = FsRequest::new();
-                    do stat_req.stat(&loop_, &path.to_c_str()) |req, uverr| {
-                        assert!(uverr.is_none());
-                        let loop_ = req.get_loop();
-                        let stat = req.get_stat();
-                        let sz: uint = stat.st_size as uint;
-                        assert!(sz > 0);
-                        let close_req = FsRequest::new();
-                        do close_req.close(&loop_, fd) |req, uverr| {
-                            assert!(uverr.is_none());
-                            let loop_ = req.get_loop();
-                            let unlink_req = FsRequest::new();
-                            do unlink_req.unlink(&loop_,
-                                                 &path.to_c_str()) |req,uverr| {
-                                assert!(uverr.is_none());
-                                let loop_ = req.get_loop();
-                                let stat_req = FsRequest::new();
-                                do stat_req.stat(&loop_,
-                                                 &path.to_c_str()) |_, uverr| {
-                                    // should cause an error because the
-                                    // file doesn't exist anymore
-                                    assert!(uverr.is_some());
-                                };
-                            };
-                        };
-                    };
-                };
-            };
-            loop_.run();
-            loop_.close();
-        }
-    }
-
-    #[test]
-    fn file_test_mk_rm_dir() {
-        do run_in_bare_thread {
-            let mut loop_ = Loop::new();
-            let path = "./tmp/mk_rm_dir";
-            let mode = S_IWUSR |
-                S_IRUSR;
-            let mkdir_req = FsRequest::new();
-            do mkdir_req.mkdir(&loop_, &path.to_c_str(),
-                               mode as int) |req,uverr| {
-                assert!(uverr.is_none());
-                let loop_ = req.get_loop();
-                let stat_req = FsRequest::new();
-                do stat_req.stat(&loop_, &path.to_c_str()) |req, uverr| {
-                    assert!(uverr.is_none());
-                    let loop_ = req.get_loop();
-                    let stat = req.get_stat();
-                    naive_print(&loop_, format!("{:?}", stat));
-                    assert!(stat.is_dir());
-                    let rmdir_req = FsRequest::new();
-                    do rmdir_req.rmdir(&loop_, &path.to_c_str()) |req,uverr| {
-                        assert!(uverr.is_none());
-                        let loop_ = req.get_loop();
-                        let stat_req = FsRequest::new();
-                        do stat_req.stat(&loop_, &path.to_c_str()) |_req, uverr| {
-                            assert!(uverr.is_some());
-                        }
-                    }
-                }
-            }
-            loop_.run();
-            loop_.close();
-        }
-    }
-    #[test]
-    fn file_test_mkdir_chokes_on_double_create() {
-        do run_in_bare_thread {
-            let mut loop_ = Loop::new();
-            let path = "./tmp/double_create_dir";
-            let mode = S_IWUSR |
-                S_IRUSR;
-            let mkdir_req = FsRequest::new();
-            do mkdir_req.mkdir(&loop_, &path.to_c_str(), mode as int) |req,uverr| {
-                assert!(uverr.is_none());
-                let loop_ = req.get_loop();
-                let mkdir_req = FsRequest::new();
-                do mkdir_req.mkdir(&loop_, &path.to_c_str(),
-                                   mode as int) |req,uverr| {
-                    assert!(uverr.is_some());
-                    let loop_ = req.get_loop();
-                    let _stat = req.get_stat();
-                    let rmdir_req = FsRequest::new();
-                    do rmdir_req.rmdir(&loop_, &path.to_c_str()) |req,uverr| {
-                        assert!(uverr.is_none());
-                        let _loop = req.get_loop();
-                    }
-                }
-            }
-            loop_.run();
-            loop_.close();
-        }
-    }
-    #[test]
-    fn file_test_rmdir_chokes_on_nonexistant_path() {
-        do run_in_bare_thread {
-            let mut loop_ = Loop::new();
-            let path = "./tmp/never_existed_dir";
-            let rmdir_req = FsRequest::new();
-            do rmdir_req.rmdir(&loop_, &path.to_c_str()) |_req, uverr| {
-                assert!(uverr.is_some());
-            }
-            loop_.run();
-            loop_.close();
-        }
-    }
-}
diff --git a/src/libstd/rt/uv/idle.rs b/src/libstd/rt/uv/idle.rs
deleted file mode 100644 (file)
index 40f0750..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2013 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 libc::c_int;
-use option::Some;
-use rt::uv::uvll;
-use rt::uv::{Watcher, Loop, NativeHandle, IdleCallback};
-use rt::uv::status_to_maybe_uv_error;
-
-pub struct IdleWatcher(*uvll::uv_idle_t);
-impl Watcher for IdleWatcher { }
-
-impl IdleWatcher {
-    pub fn new(loop_: &mut Loop) -> IdleWatcher {
-        unsafe {
-            let handle = uvll::malloc_handle(uvll::UV_IDLE);
-            assert!(handle.is_not_null());
-            assert_eq!(uvll::idle_init(loop_.native_handle(), handle), 0);
-            let mut watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
-            watcher.install_watcher_data();
-            return watcher
-        }
-    }
-
-    pub fn start(&mut self, cb: IdleCallback) {
-        {
-            let data = self.get_watcher_data();
-            data.idle_cb = Some(cb);
-        }
-
-        unsafe {
-            assert_eq!(uvll::idle_start(self.native_handle(), idle_cb), 0)
-        }
-    }
-
-    pub fn restart(&mut self) {
-        unsafe {
-            assert!(self.get_watcher_data().idle_cb.is_some());
-            assert_eq!(uvll::idle_start(self.native_handle(), idle_cb), 0)
-        }
-    }
-
-    pub fn stop(&mut self) {
-        // NB: Not resetting the Rust idle_cb to None here because `stop` is
-        // likely called from *within* the idle callback, causing a use after
-        // free
-
-        unsafe {
-            assert_eq!(uvll::idle_stop(self.native_handle()), 0);
-        }
-    }
-}
-
-impl NativeHandle<*uvll::uv_idle_t> for IdleWatcher {
-    fn from_native_handle(handle: *uvll::uv_idle_t) -> IdleWatcher {
-        IdleWatcher(handle)
-    }
-    fn native_handle(&self) -> *uvll::uv_idle_t {
-        match self { &IdleWatcher(ptr) => ptr }
-    }
-}
-
-extern fn idle_cb(handle: *uvll::uv_idle_t, status: c_int) {
-    let mut idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
-    let data = idle_watcher.get_watcher_data();
-    let cb: &IdleCallback = data.idle_cb.get_ref();
-    let status = status_to_maybe_uv_error(status);
-    (*cb)(idle_watcher, status);
-}
-
-#[cfg(test)]
-mod test {
-
-    use rt::uv::Loop;
-    use super::*;
-    use unstable::run_in_bare_thread;
-
-    #[test]
-    #[ignore(reason = "valgrind - loop destroyed before watcher?")]
-    fn idle_new_then_close() {
-        do run_in_bare_thread {
-            let mut loop_ = Loop::new();
-            let idle_watcher = { IdleWatcher::new(&mut loop_) };
-            idle_watcher.close(||());
-        }
-    }
-
-    #[test]
-    fn idle_smoke_test() {
-        do run_in_bare_thread {
-            let mut loop_ = Loop::new();
-            let mut idle_watcher = { IdleWatcher::new(&mut loop_) };
-            let mut count = 10;
-            let count_ptr: *mut int = &mut count;
-            do idle_watcher.start |idle_watcher, status| {
-                let mut idle_watcher = idle_watcher;
-                assert!(status.is_none());
-                if unsafe { *count_ptr == 10 } {
-                    idle_watcher.stop();
-                    idle_watcher.close(||());
-                } else {
-                    unsafe { *count_ptr = *count_ptr + 1; }
-                }
-            }
-            loop_.run();
-            loop_.close();
-            assert_eq!(count, 10);
-        }
-    }
-
-    #[test]
-    fn idle_start_stop_start() {
-        do run_in_bare_thread {
-            let mut loop_ = Loop::new();
-            let mut idle_watcher = { IdleWatcher::new(&mut loop_) };
-            do idle_watcher.start |idle_watcher, status| {
-                let mut idle_watcher = idle_watcher;
-                assert!(status.is_none());
-                idle_watcher.stop();
-                do idle_watcher.start |idle_watcher, status| {
-                    assert!(status.is_none());
-                    let mut idle_watcher = idle_watcher;
-                    idle_watcher.stop();
-                    idle_watcher.close(||());
-                }
-            }
-            loop_.run();
-            loop_.close();
-        }
-    }
-}
diff --git a/src/libstd/rt/uv/mod.rs b/src/libstd/rt/uv/mod.rs
deleted file mode 100644 (file)
index b0e2569..0000000
+++ /dev/null
@@ -1,416 +0,0 @@
-// Copyright 2013 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.
-
-/*!
-
-Bindings to libuv, along with the default implementation of `std::rt::rtio`.
-
-UV types consist of the event loop (Loop), Watchers, Requests and
-Callbacks.
-
-Watchers and Requests encapsulate pointers to uv *handles*, which have
-subtyping relationships with each other.  This subtyping is reflected
-in the bindings with explicit or implicit coercions. For example, an
-upcast from TcpWatcher to StreamWatcher is done with
-`tcp_watcher.as_stream()`. In other cases a callback on a specific
-type of watcher will be passed a watcher of a supertype.
-
-Currently all use of Request types (connect/write requests) are
-encapsulated in the bindings and don't need to be dealt with by the
-caller.
-
-# Safety note
-
-Due to the complex lifecycle of uv handles, as well as compiler bugs,
-this module is not memory safe and requires explicit memory management,
-via `close` and `delete` methods.
-
-*/
-
-use container::Container;
-use option::*;
-use str::raw::from_c_str;
-use to_str::ToStr;
-use ptr::RawPtr;
-use vec;
-use vec::ImmutableVector;
-use ptr;
-use str;
-use libc::{c_void, c_int, size_t, malloc, free};
-use cast::transmute;
-use ptr::null;
-use unstable::finally::Finally;
-use rt::io::net::ip::SocketAddr;
-use rt::io::signal::Signum;
-
-use rt::io::IoError;
-
-//#[cfg(test)] use unstable::run_in_bare_thread;
-
-pub use self::file::{FsRequest};
-pub use self::net::{StreamWatcher, TcpWatcher, UdpWatcher};
-pub use self::idle::IdleWatcher;
-pub use self::timer::TimerWatcher;
-pub use self::async::AsyncWatcher;
-pub use self::process::Process;
-pub use self::pipe::Pipe;
-pub use self::signal::SignalWatcher;
-
-/// The implementation of `rtio` for libuv
-pub mod uvio;
-
-/// C bindings to libuv
-pub mod uvll;
-
-pub mod file;
-pub mod net;
-pub mod idle;
-pub mod timer;
-pub mod async;
-pub mod addrinfo;
-pub mod process;
-pub mod pipe;
-pub mod tty;
-pub mod signal;
-
-/// XXX: Loop(*handle) is buggy with destructors. Normal structs
-/// with dtors may not be destructured, but tuple structs can,
-/// but the results are not correct.
-pub struct Loop {
-    priv handle: *uvll::uv_loop_t
-}
-
-pub struct Handle(*uvll::uv_handle_t);
-
-impl Watcher for Handle {}
-impl NativeHandle<*uvll::uv_handle_t> for Handle {
-    fn from_native_handle(h: *uvll::uv_handle_t) -> Handle { Handle(h) }
-    fn native_handle(&self) -> *uvll::uv_handle_t { **self }
-}
-
-/// The trait implemented by uv 'watchers' (handles). Watchers are
-/// non-owning wrappers around the uv handles and are not completely
-/// safe - there may be multiple instances for a single underlying
-/// handle.  Watchers are generally created, then `start`ed, `stop`ed
-/// and `close`ed, but due to their complex life cycle may not be
-/// entirely memory safe if used in unanticipated patterns.
-pub trait Watcher { }
-
-pub trait Request { }
-
-/// A type that wraps a native handle
-pub trait NativeHandle<T> {
-    fn from_native_handle(T) -> Self;
-    fn native_handle(&self) -> T;
-}
-
-impl Loop {
-    pub fn new() -> Loop {
-        let handle = unsafe { uvll::loop_new() };
-        assert!(handle.is_not_null());
-        NativeHandle::from_native_handle(handle)
-    }
-
-    pub fn run(&mut self) {
-        unsafe { uvll::run(self.native_handle()) };
-    }
-
-    pub fn close(&mut self) {
-        unsafe { uvll::loop_delete(self.native_handle()) };
-    }
-}
-
-impl NativeHandle<*uvll::uv_loop_t> for Loop {
-    fn from_native_handle(handle: *uvll::uv_loop_t) -> Loop {
-        Loop { handle: handle }
-    }
-    fn native_handle(&self) -> *uvll::uv_loop_t {
-        self.handle
-    }
-}
-
-// XXX: The uv alloc callback also has a *uv_handle_t arg
-pub type AllocCallback = ~fn(uint) -> Buf;
-pub type ReadCallback = ~fn(StreamWatcher, int, Buf, Option<UvError>);
-pub type NullCallback = ~fn();
-pub type IdleCallback = ~fn(IdleWatcher, Option<UvError>);
-pub type ConnectionCallback = ~fn(StreamWatcher, Option<UvError>);
-pub type FsCallback = ~fn(&mut FsRequest, Option<UvError>);
-// first int is exit_status, second is term_signal
-pub type ExitCallback = ~fn(Process, int, int, Option<UvError>);
-pub type TimerCallback = ~fn(TimerWatcher, Option<UvError>);
-pub type AsyncCallback = ~fn(AsyncWatcher, Option<UvError>);
-pub type UdpReceiveCallback = ~fn(UdpWatcher, int, Buf, SocketAddr, uint, Option<UvError>);
-pub type UdpSendCallback = ~fn(UdpWatcher, Option<UvError>);
-pub type SignalCallback = ~fn(SignalWatcher, Signum);
-
-
-/// Callbacks used by StreamWatchers, set as custom data on the foreign handle.
-/// XXX: Would be better not to have all watchers allocate room for all callback types.
-struct WatcherData {
-    read_cb: Option<ReadCallback>,
-    write_cb: Option<ConnectionCallback>,
-    connect_cb: Option<ConnectionCallback>,
-    close_cb: Option<NullCallback>,
-    alloc_cb: Option<AllocCallback>,
-    idle_cb: Option<IdleCallback>,
-    timer_cb: Option<TimerCallback>,
-    async_cb: Option<AsyncCallback>,
-    udp_recv_cb: Option<UdpReceiveCallback>,
-    udp_send_cb: Option<UdpSendCallback>,
-    exit_cb: Option<ExitCallback>,
-    signal_cb: Option<SignalCallback>,
-}
-
-pub trait WatcherInterop {
-    fn event_loop(&self) -> Loop;
-    fn install_watcher_data(&mut self);
-    fn get_watcher_data<'r>(&'r mut self) -> &'r mut WatcherData;
-    fn drop_watcher_data(&mut self);
-    fn close(self, cb: NullCallback);
-    fn close_async(self);
-}
-
-impl<H, W: Watcher + NativeHandle<*H>> WatcherInterop for W {
-    /// Get the uv event loop from a Watcher
-    fn event_loop(&self) -> Loop {
-        unsafe {
-            let handle = self.native_handle();
-            let loop_ = uvll::get_loop_for_uv_handle(handle);
-            NativeHandle::from_native_handle(loop_)
-        }
-    }
-
-    fn install_watcher_data(&mut self) {
-        unsafe {
-            let data = ~WatcherData {
-                read_cb: None,
-                write_cb: None,
-                connect_cb: None,
-                close_cb: None,
-                alloc_cb: None,
-                idle_cb: None,
-                timer_cb: None,
-                async_cb: None,
-                udp_recv_cb: None,
-                udp_send_cb: None,
-                exit_cb: None,
-                signal_cb: None,
-            };
-            let data = transmute::<~WatcherData, *c_void>(data);
-            uvll::set_data_for_uv_handle(self.native_handle(), data);
-        }
-    }
-
-    fn get_watcher_data<'r>(&'r mut self) -> &'r mut WatcherData {
-        unsafe {
-            let data = uvll::get_data_for_uv_handle(self.native_handle());
-            let data = transmute::<&*c_void, &mut ~WatcherData>(&data);
-            return &mut **data;
-        }
-    }
-
-    fn drop_watcher_data(&mut self) {
-        unsafe {
-            let data = uvll::get_data_for_uv_handle(self.native_handle());
-            let _data = transmute::<*c_void, ~WatcherData>(data);
-            uvll::set_data_for_uv_handle(self.native_handle(), null::<()>());
-        }
-    }
-
-    fn close(mut self, cb: NullCallback) {
-        {
-            let data = self.get_watcher_data();
-            assert!(data.close_cb.is_none());
-            data.close_cb = Some(cb);
-        }
-
-        unsafe { uvll::close(self.native_handle(), close_cb); }
-
-        extern fn close_cb(handle: *uvll::uv_handle_t) {
-            let mut h: Handle = NativeHandle::from_native_handle(handle);
-            h.get_watcher_data().close_cb.take_unwrap()();
-            h.drop_watcher_data();
-            unsafe { uvll::free_handle(handle as *c_void) }
-        }
-    }
-
-    fn close_async(self) {
-        unsafe { uvll::close(self.native_handle(), close_cb); }
-
-        extern fn close_cb(handle: *uvll::uv_handle_t) {
-            let mut h: Handle = NativeHandle::from_native_handle(handle);
-            h.drop_watcher_data();
-            unsafe { uvll::free_handle(handle as *c_void) }
-        }
-    }
-}
-
-// XXX: Need to define the error constants like EOF so they can be
-// compared to the UvError type
-
-pub struct UvError(c_int);
-
-impl UvError {
-    pub fn name(&self) -> ~str {
-        unsafe {
-            let inner = match self { &UvError(a) => a };
-            let name_str = uvll::err_name(inner);
-            assert!(name_str.is_not_null());
-            from_c_str(name_str)
-        }
-    }
-
-    pub fn desc(&self) -> ~str {
-        unsafe {
-            let inner = match self { &UvError(a) => a };
-            let desc_str = uvll::strerror(inner);
-            assert!(desc_str.is_not_null());
-            from_c_str(desc_str)
-        }
-    }
-
-    pub fn is_eof(&self) -> bool {
-        **self == uvll::EOF
-    }
-}
-
-impl ToStr for UvError {
-    fn to_str(&self) -> ~str {
-        format!("{}: {}", self.name(), self.desc())
-    }
-}
-
-#[test]
-fn error_smoke_test() {
-    let err: UvError = UvError(uvll::EOF);
-    assert_eq!(err.to_str(), ~"EOF: end of file");
-}
-
-pub fn uv_error_to_io_error(uverr: UvError) -> IoError {
-    unsafe {
-        // Importing error constants
-        use rt::uv::uvll::*;
-        use rt::io::*;
-
-        // uv error descriptions are static
-        let c_desc = uvll::strerror(*uverr);
-        let desc = str::raw::c_str_to_static_slice(c_desc);
-
-        let kind = match *uverr {
-            UNKNOWN => OtherIoError,
-            OK => OtherIoError,
-            EOF => EndOfFile,
-            EACCES => PermissionDenied,
-            ECONNREFUSED => ConnectionRefused,
-            ECONNRESET => ConnectionReset,
-            ENOTCONN => NotConnected,
-            EPIPE => BrokenPipe,
-            ECONNABORTED => ConnectionAborted,
-            err => {
-                rtdebug!("uverr.code {}", err as int);
-                // XXX: Need to map remaining uv error types
-                OtherIoError
-            }
-        };
-
-        IoError {
-            kind: kind,
-            desc: desc,
-            detail: None
-        }
-    }
-}
-
-/// Given a uv handle, convert a callback status to a UvError
-pub fn status_to_maybe_uv_error(status: c_int) -> Option<UvError>
-{
-    if status >= 0 {
-        None
-    } else {
-        Some(UvError(status))
-    }
-}
-
-/// The uv buffer type
-pub type Buf = uvll::uv_buf_t;
-
-pub fn empty_buf() -> Buf {
-    uvll::uv_buf_t {
-        base: null(),
-        len: 0,
-    }
-}
-
-/// Borrow a slice to a Buf
-pub fn slice_to_uv_buf(v: &[u8]) -> Buf {
-    let data = vec::raw::to_ptr(v);
-    unsafe { uvll::buf_init(data, v.len()) }
-}
-
-// XXX: Do these conversions without copying
-
-/// Transmute an owned vector to a Buf
-pub fn vec_to_uv_buf(v: ~[u8]) -> Buf {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    unsafe {
-        let data = malloc(v.len() as size_t) as *u8;
-        assert!(data.is_not_null());
-        do v.as_imm_buf |b, l| {
-            let data = data as *mut u8;
-            ptr::copy_memory(data, b, l)
-        }
-        uvll::buf_init(data, v.len())
-    }
-}
-
-/// Transmute a Buf that was once a ~[u8] back to ~[u8]
-pub fn vec_from_uv_buf(buf: Buf) -> Option<~[u8]> {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    if !(buf.len == 0 && buf.base.is_null()) {
-        let v = unsafe { vec::from_buf(buf.base, buf.len as uint) };
-        unsafe { free(buf.base as *c_void) };
-        return Some(v);
-    } else {
-        // No buffer
-        rtdebug!("No buffer!");
-        return None;
-    }
-}
-/*
-#[test]
-fn test_slice_to_uv_buf() {
-    let slice = [0, .. 20];
-    let buf = slice_to_uv_buf(slice);
-
-    assert!(buf.len == 20);
-
-    unsafe {
-        let base = transmute::<*u8, *mut u8>(buf.base);
-        (*base) = 1;
-        (*ptr::mut_offset(base, 1)) = 2;
-    }
-
-    assert!(slice[0] == 1);
-    assert!(slice[1] == 2);
-}
-
-
-#[test]
-fn loop_smoke_test() {
-    do run_in_bare_thread {
-        let mut loop_ = Loop::new();
-        loop_.run();
-        loop_.close();
-    }
-}
-*/
diff --git a/src/libstd/rt/uv/net.rs b/src/libstd/rt/uv/net.rs
deleted file mode 100644 (file)
index 77de834..0000000
+++ /dev/null
@@ -1,853 +0,0 @@
-// Copyright 2013 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 prelude::*;
-use libc::{size_t, ssize_t, c_int, c_void, c_uint};
-use rt::uv::uvll;
-use rt::uv::uvll::*;
-use rt::uv::{AllocCallback, ConnectionCallback, ReadCallback, UdpReceiveCallback, UdpSendCallback};
-use rt::uv::{Loop, Watcher, Request, UvError, Buf, NativeHandle,
-             status_to_maybe_uv_error, empty_buf};
-use rt::io::net::ip::{SocketAddr, Ipv4Addr, Ipv6Addr};
-use vec;
-use str;
-use from_str::{FromStr};
-
-pub struct UvAddrInfo(*uvll::addrinfo);
-
-pub enum UvSocketAddr {
-    UvIpv4SocketAddr(*sockaddr_in),
-    UvIpv6SocketAddr(*sockaddr_in6),
-}
-
-pub fn sockaddr_to_UvSocketAddr(addr: *uvll::sockaddr) -> UvSocketAddr {
-    unsafe {
-        assert!((is_ip4_addr(addr) || is_ip6_addr(addr)));
-        assert!(!(is_ip4_addr(addr) && is_ip6_addr(addr)));
-        match addr {
-            _ if is_ip4_addr(addr) => UvIpv4SocketAddr(addr as *uvll::sockaddr_in),
-            _ if is_ip6_addr(addr) => UvIpv6SocketAddr(addr as *uvll::sockaddr_in6),
-            _ => fail!(),
-        }
-    }
-}
-
-fn socket_addr_as_uv_socket_addr<T>(addr: SocketAddr, f: &fn(UvSocketAddr) -> T) -> T {
-    let malloc = match addr.ip {
-        Ipv4Addr(*) => malloc_ip4_addr,
-        Ipv6Addr(*) => malloc_ip6_addr,
-    };
-    let wrap = match addr.ip {
-        Ipv4Addr(*) => UvIpv4SocketAddr,
-        Ipv6Addr(*) => UvIpv6SocketAddr,
-    };
-    let free = match addr.ip {
-        Ipv4Addr(*) => free_ip4_addr,
-        Ipv6Addr(*) => free_ip6_addr,
-    };
-
-    let addr = unsafe { malloc(addr.ip.to_str(), addr.port as int) };
-    do (|| {
-        f(wrap(addr))
-    }).finally {
-        unsafe { free(addr) };
-    }
-}
-
-fn uv_socket_addr_as_socket_addr<T>(addr: UvSocketAddr, f: &fn(SocketAddr) -> T) -> T {
-    let ip_size = match addr {
-        UvIpv4SocketAddr(*) => 4/*groups of*/ * 3/*digits separated by*/ + 3/*periods*/,
-        UvIpv6SocketAddr(*) => 8/*groups of*/ * 4/*hex digits separated by*/ + 7 /*colons*/,
-    };
-    let ip_name = {
-        let buf = vec::from_elem(ip_size + 1 /*null terminated*/, 0u8);
-        unsafe {
-            let buf_ptr = vec::raw::to_ptr(buf);
-            match addr {
-                UvIpv4SocketAddr(addr) => uvll::ip4_name(addr, buf_ptr, ip_size as size_t),
-                UvIpv6SocketAddr(addr) => uvll::ip6_name(addr, buf_ptr, ip_size as size_t),
-            }
-        };
-        buf
-    };
-    let ip_port = unsafe {
-        let port = match addr {
-            UvIpv4SocketAddr(addr) => uvll::ip4_port(addr),
-            UvIpv6SocketAddr(addr) => uvll::ip6_port(addr),
-        };
-        port as u16
-    };
-    let ip_str = str::from_utf8_slice(ip_name).trim_right_chars(&'\x00');
-    let ip_addr = FromStr::from_str(ip_str).unwrap();
-
-    // finally run the closure
-    f(SocketAddr { ip: ip_addr, port: ip_port })
-}
-
-pub fn uv_socket_addr_to_socket_addr(addr: UvSocketAddr) -> SocketAddr {
-    use util;
-    uv_socket_addr_as_socket_addr(addr, util::id)
-}
-
-#[cfg(test)]
-#[test]
-fn test_ip4_conversion() {
-    use rt;
-    let ip4 = rt::test::next_test_ip4();
-    assert_eq!(ip4, socket_addr_as_uv_socket_addr(ip4, uv_socket_addr_to_socket_addr));
-}
-
-#[cfg(test)]
-#[test]
-fn test_ip6_conversion() {
-    use rt;
-    let ip6 = rt::test::next_test_ip6();
-    assert_eq!(ip6, socket_addr_as_uv_socket_addr(ip6, uv_socket_addr_to_socket_addr));
-}
-
-// uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t, uv_tty_t
-// and uv_file_t
-pub struct StreamWatcher(*uvll::uv_stream_t);
-impl Watcher for StreamWatcher { }
-
-impl StreamWatcher {
-    pub fn read_start(&mut self, alloc: AllocCallback, cb: ReadCallback) {
-        unsafe {
-            match uvll::read_start(self.native_handle(), alloc_cb, read_cb) {
-                0 => {
-                    let data = self.get_watcher_data();
-                    data.alloc_cb = Some(alloc);
-                    data.read_cb = Some(cb);
-                }
-                n => {
-                    cb(*self, 0, empty_buf(), Some(UvError(n)))
-                }
-            }
-        }
-
-        extern fn alloc_cb(stream: *uvll::uv_stream_t, suggested_size: size_t) -> Buf {
-            let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(stream);
-            let alloc_cb = stream_watcher.get_watcher_data().alloc_cb.get_ref();
-            return (*alloc_cb)(suggested_size as uint);
-        }
-
-        extern fn read_cb(stream: *uvll::uv_stream_t, nread: ssize_t, buf: Buf) {
-            rtdebug!("buf addr: {}", buf.base);
-            rtdebug!("buf len: {}", buf.len);
-            let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(stream);
-            let cb = stream_watcher.get_watcher_data().read_cb.get_ref();
-            let status = status_to_maybe_uv_error(nread as c_int);
-            (*cb)(stream_watcher, nread as int, buf, status);
-        }
-    }
-
-    pub fn read_stop(&mut self) {
-        // It would be nice to drop the alloc and read callbacks here,
-        // but read_stop may be called from inside one of them and we
-        // would end up freeing the in-use environment
-        let handle = self.native_handle();
-        unsafe { assert_eq!(uvll::read_stop(handle), 0); }
-    }
-
-    pub fn write(&mut self, buf: Buf, cb: ConnectionCallback) {
-        let req = WriteRequest::new();
-        return unsafe {
-            match uvll::write(req.native_handle(), self.native_handle(),
-                              [buf], write_cb) {
-                0 => {
-                    let data = self.get_watcher_data();
-                    assert!(data.write_cb.is_none());
-                    data.write_cb = Some(cb);
-                }
-                n => {
-                    req.delete();
-                    cb(*self, Some(UvError(n)))
-                }
-            }
-        };
-
-        extern fn write_cb(req: *uvll::uv_write_t, status: c_int) {
-            let write_request: WriteRequest = NativeHandle::from_native_handle(req);
-            let mut stream_watcher = write_request.stream();
-            write_request.delete();
-            let cb = stream_watcher.get_watcher_data().write_cb.take_unwrap();
-            let status = status_to_maybe_uv_error(status);
-            cb(stream_watcher, status);
-        }
-    }
-
-
-    pub fn listen(&mut self, cb: ConnectionCallback) -> Result<(), UvError> {
-        {
-            let data = self.get_watcher_data();
-            assert!(data.connect_cb.is_none());
-            data.connect_cb = Some(cb);
-        }
-
-        return unsafe {
-            static BACKLOG: c_int = 128; // XXX should be configurable
-            match uvll::listen(self.native_handle(), BACKLOG, connection_cb) {
-                0 => Ok(()),
-                n => Err(UvError(n))
-            }
-        };
-
-        extern fn connection_cb(handle: *uvll::uv_stream_t, status: c_int) {
-            rtdebug!("connection_cb");
-            let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(handle);
-            let cb = stream_watcher.get_watcher_data().connect_cb.get_ref();
-            let status = status_to_maybe_uv_error(status);
-            (*cb)(stream_watcher, status);
-        }
-    }
-
-    pub fn accept(&mut self, stream: StreamWatcher) {
-        let self_handle = self.native_handle() as *c_void;
-        let stream_handle = stream.native_handle() as *c_void;
-        assert_eq!(0, unsafe { uvll::accept(self_handle, stream_handle) } );
-    }
-}
-
-impl NativeHandle<*uvll::uv_stream_t> for StreamWatcher {
-    fn from_native_handle(handle: *uvll::uv_stream_t) -> StreamWatcher {
-        StreamWatcher(handle)
-    }
-    fn native_handle(&self) -> *uvll::uv_stream_t {
-        match self { &StreamWatcher(ptr) => ptr }
-    }
-}
-
-pub struct TcpWatcher(*uvll::uv_tcp_t);
-impl Watcher for TcpWatcher { }
-
-impl TcpWatcher {
-    pub fn new(loop_: &Loop) -> TcpWatcher {
-        unsafe {
-            let handle = malloc_handle(UV_TCP);
-            assert!(handle.is_not_null());
-            assert_eq!(0, uvll::tcp_init(loop_.native_handle(), handle));
-            let mut watcher: TcpWatcher = NativeHandle::from_native_handle(handle);
-            watcher.install_watcher_data();
-            return watcher;
-        }
-    }
-
-    pub fn bind(&mut self, address: SocketAddr) -> Result<(), UvError> {
-        do socket_addr_as_uv_socket_addr(address) |addr| {
-            let result = unsafe {
-                match addr {
-                    UvIpv4SocketAddr(addr) => uvll::tcp_bind(self.native_handle(), addr),
-                    UvIpv6SocketAddr(addr) => uvll::tcp_bind6(self.native_handle(), addr),
-                }
-            };
-            match result {
-                0 => Ok(()),
-                _ => Err(UvError(result)),
-            }
-        }
-    }
-
-    pub fn connect(&mut self, address: SocketAddr, cb: ConnectionCallback) {
-        unsafe {
-            assert!(self.get_watcher_data().connect_cb.is_none());
-            self.get_watcher_data().connect_cb = Some(cb);
-
-            let connect_handle = ConnectRequest::new().native_handle();
-            rtdebug!("connect_t: {}", connect_handle);
-            do socket_addr_as_uv_socket_addr(address) |addr| {
-                let result = match addr {
-                    UvIpv4SocketAddr(addr) => uvll::tcp_connect(connect_handle,
-                                                      self.native_handle(), addr, connect_cb),
-                    UvIpv6SocketAddr(addr) => uvll::tcp_connect6(connect_handle,
-                                                       self.native_handle(), addr, connect_cb),
-                };
-                assert_eq!(0, result);
-            }
-
-            extern fn connect_cb(req: *uvll::uv_connect_t, status: c_int) {
-                rtdebug!("connect_t: {}", req);
-                let connect_request: ConnectRequest = NativeHandle::from_native_handle(req);
-                let mut stream_watcher = connect_request.stream();
-                connect_request.delete();
-                let cb = stream_watcher.get_watcher_data().connect_cb.take_unwrap();
-                let status = status_to_maybe_uv_error(status);
-                cb(stream_watcher, status);
-            }
-        }
-    }
-
-    pub fn as_stream(&self) -> StreamWatcher {
-        NativeHandle::from_native_handle(self.native_handle() as *uvll::uv_stream_t)
-    }
-}
-
-impl NativeHandle<*uvll::uv_tcp_t> for TcpWatcher {
-    fn from_native_handle(handle: *uvll::uv_tcp_t) -> TcpWatcher {
-        TcpWatcher(handle)
-    }
-    fn native_handle(&self) -> *uvll::uv_tcp_t {
-        match self { &TcpWatcher(ptr) => ptr }
-    }
-}
-
-pub struct UdpWatcher(*uvll::uv_udp_t);
-impl Watcher for UdpWatcher { }
-
-impl UdpWatcher {
-    pub fn new(loop_: &Loop) -> UdpWatcher {
-        unsafe {
-            let handle = malloc_handle(UV_UDP);
-            assert!(handle.is_not_null());
-            assert_eq!(0, uvll::udp_init(loop_.native_handle(), handle));
-            let mut watcher: UdpWatcher = NativeHandle::from_native_handle(handle);
-            watcher.install_watcher_data();
-            return watcher;
-        }
-    }
-
-    pub fn bind(&mut self, address: SocketAddr) -> Result<(), UvError> {
-        do socket_addr_as_uv_socket_addr(address) |addr| {
-            let result = unsafe {
-                match addr {
-                    UvIpv4SocketAddr(addr) => uvll::udp_bind(self.native_handle(), addr, 0u32),
-                    UvIpv6SocketAddr(addr) => uvll::udp_bind6(self.native_handle(), addr, 0u32),
-                }
-            };
-            match result {
-                0 => Ok(()),
-                _ => Err(UvError(result)),
-            }
-        }
-    }
-
-    pub fn recv_start(&mut self, alloc: AllocCallback, cb: UdpReceiveCallback) {
-        {
-            let data = self.get_watcher_data();
-            data.alloc_cb = Some(alloc);
-            data.udp_recv_cb = Some(cb);
-        }
-
-        unsafe { uvll::udp_recv_start(self.native_handle(), alloc_cb, recv_cb); }
-
-        extern fn alloc_cb(handle: *uvll::uv_udp_t, suggested_size: size_t) -> Buf {
-            let mut udp_watcher: UdpWatcher = NativeHandle::from_native_handle(handle);
-            let alloc_cb = udp_watcher.get_watcher_data().alloc_cb.get_ref();
-            return (*alloc_cb)(suggested_size as uint);
-        }
-
-        extern fn recv_cb(handle: *uvll::uv_udp_t, nread: ssize_t, buf: Buf,
-                          addr: *uvll::sockaddr, flags: c_uint) {
-            // When there's no data to read the recv callback can be a no-op.
-            // This can happen if read returns EAGAIN/EWOULDBLOCK. By ignoring
-            // this we just drop back to kqueue and wait for the next callback.
-            if nread == 0 {
-                return;
-            }
-
-            rtdebug!("buf addr: {}", buf.base);
-            rtdebug!("buf len: {}", buf.len);
-            let mut udp_watcher: UdpWatcher = NativeHandle::from_native_handle(handle);
-            let cb = udp_watcher.get_watcher_data().udp_recv_cb.get_ref();
-            let status = status_to_maybe_uv_error(nread as c_int);
-            let addr = uv_socket_addr_to_socket_addr(sockaddr_to_UvSocketAddr(addr));
-            (*cb)(udp_watcher, nread as int, buf, addr, flags as uint, status);
-        }
-    }
-
-    pub fn recv_stop(&mut self) {
-        unsafe { uvll::udp_recv_stop(self.native_handle()); }
-    }
-
-    pub fn send(&mut self, buf: Buf, address: SocketAddr, cb: UdpSendCallback) {
-        {
-            let data = self.get_watcher_data();
-            assert!(data.udp_send_cb.is_none());
-            data.udp_send_cb = Some(cb);
-        }
-
-        let req = UdpSendRequest::new();
-        do socket_addr_as_uv_socket_addr(address) |addr| {
-            let result = unsafe {
-                match addr {
-                    UvIpv4SocketAddr(addr) => uvll::udp_send(req.native_handle(),
-                                                   self.native_handle(), [buf], addr, send_cb),
-                    UvIpv6SocketAddr(addr) => uvll::udp_send6(req.native_handle(),
-                                                    self.native_handle(), [buf], addr, send_cb),
-                }
-            };
-            assert_eq!(0, result);
-        }
-
-        extern fn send_cb(req: *uvll::uv_udp_send_t, status: c_int) {
-            let send_request: UdpSendRequest = NativeHandle::from_native_handle(req);
-            let mut udp_watcher = send_request.handle();
-            send_request.delete();
-            let cb = udp_watcher.get_watcher_data().udp_send_cb.take_unwrap();
-            let status = status_to_maybe_uv_error(status);
-            cb(udp_watcher, status);
-        }
-    }
-}
-
-impl NativeHandle<*uvll::uv_udp_t> for UdpWatcher {
-    fn from_native_handle(handle: *uvll::uv_udp_t) -> UdpWatcher {
-        UdpWatcher(handle)
-    }
-    fn native_handle(&self) -> *uvll::uv_udp_t {
-        match self { &UdpWatcher(ptr) => ptr }
-    }
-}
-
-// uv_connect_t is a subclass of uv_req_t
-pub struct ConnectRequest(*uvll::uv_connect_t);
-impl Request for ConnectRequest { }
-
-impl ConnectRequest {
-
-    pub fn new() -> ConnectRequest {
-        let connect_handle = unsafe { malloc_req(UV_CONNECT) };
-        assert!(connect_handle.is_not_null());
-        ConnectRequest(connect_handle as *uvll::uv_connect_t)
-    }
-
-    fn stream(&self) -> StreamWatcher {
-        unsafe {
-            let stream_handle = uvll::get_stream_handle_from_connect_req(self.native_handle());
-            NativeHandle::from_native_handle(stream_handle)
-        }
-    }
-
-    fn delete(self) {
-        unsafe { free_req(self.native_handle() as *c_void) }
-    }
-}
-
-impl NativeHandle<*uvll::uv_connect_t> for ConnectRequest {
-    fn from_native_handle(handle: *uvll:: uv_connect_t) -> ConnectRequest {
-        ConnectRequest(handle)
-    }
-    fn native_handle(&self) -> *uvll::uv_connect_t {
-        match self { &ConnectRequest(ptr) => ptr }
-    }
-}
-
-pub struct WriteRequest(*uvll::uv_write_t);
-
-impl Request for WriteRequest { }
-
-impl WriteRequest {
-    pub fn new() -> WriteRequest {
-        let write_handle = unsafe { malloc_req(UV_WRITE) };
-        assert!(write_handle.is_not_null());
-        WriteRequest(write_handle as *uvll::uv_write_t)
-    }
-
-    pub fn stream(&self) -> StreamWatcher {
-        unsafe {
-            let stream_handle = uvll::get_stream_handle_from_write_req(self.native_handle());
-            NativeHandle::from_native_handle(stream_handle)
-        }
-    }
-
-    pub fn delete(self) {
-        unsafe { free_req(self.native_handle() as *c_void) }
-    }
-}
-
-impl NativeHandle<*uvll::uv_write_t> for WriteRequest {
-    fn from_native_handle(handle: *uvll:: uv_write_t) -> WriteRequest {
-        WriteRequest(handle)
-    }
-    fn native_handle(&self) -> *uvll::uv_write_t {
-        match self { &WriteRequest(ptr) => ptr }
-    }
-}
-
-pub struct UdpSendRequest(*uvll::uv_udp_send_t);
-impl Request for UdpSendRequest { }
-
-impl UdpSendRequest {
-    pub fn new() -> UdpSendRequest {
-        let send_handle = unsafe { malloc_req(UV_UDP_SEND) };
-        assert!(send_handle.is_not_null());
-        UdpSendRequest(send_handle as *uvll::uv_udp_send_t)
-    }
-
-    pub fn handle(&self) -> UdpWatcher {
-        let send_request_handle = unsafe {
-            uvll::get_udp_handle_from_send_req(self.native_handle())
-        };
-        NativeHandle::from_native_handle(send_request_handle)
-    }
-
-    pub fn delete(self) {
-        unsafe { free_req(self.native_handle() as *c_void) }
-    }
-}
-
-impl NativeHandle<*uvll::uv_udp_send_t> for UdpSendRequest {
-    fn from_native_handle(handle: *uvll::uv_udp_send_t) -> UdpSendRequest {
-        UdpSendRequest(handle)
-    }
-    fn native_handle(&self) -> *uvll::uv_udp_send_t {
-        match self { &UdpSendRequest(ptr) => ptr }
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::*;
-    use util::ignore;
-    use cell::Cell;
-    use vec;
-    use unstable::run_in_bare_thread;
-    use rt::thread::Thread;
-    use rt::test::*;
-    use rt::uv::{Loop, AllocCallback};
-    use rt::uv::{vec_from_uv_buf, vec_to_uv_buf, slice_to_uv_buf};
-    use prelude::*;
-
-    #[test]
-    fn connect_close_ip4() {
-        do run_in_bare_thread() {
-            let mut loop_ = Loop::new();
-            let mut tcp_watcher = { TcpWatcher::new(&mut loop_) };
-            // Connect to a port where nobody is listening
-            let addr = next_test_ip4();
-            do tcp_watcher.connect(addr) |stream_watcher, status| {
-                rtdebug!("tcp_watcher.connect!");
-                assert!(status.is_some());
-                assert_eq!(status.unwrap().name(), ~"ECONNREFUSED");
-                stream_watcher.close(||());
-            }
-            loop_.run();
-            loop_.close();
-        }
-    }
-
-    #[test]
-    fn connect_close_ip6() {
-        do run_in_bare_thread() {
-            let mut loop_ = Loop::new();
-            let mut tcp_watcher = { TcpWatcher::new(&mut loop_) };
-            // Connect to a port where nobody is listening
-            let addr = next_test_ip6();
-            do tcp_watcher.connect(addr) |stream_watcher, status| {
-                rtdebug!("tcp_watcher.connect!");
-                assert!(status.is_some());
-                assert_eq!(status.unwrap().name(), ~"ECONNREFUSED");
-                stream_watcher.close(||());
-            }
-            loop_.run();
-            loop_.close();
-        }
-    }
-
-    #[test]
-    fn udp_bind_close_ip4() {
-        do run_in_bare_thread() {
-            let mut loop_ = Loop::new();
-            let mut udp_watcher = { UdpWatcher::new(&mut loop_) };
-            let addr = next_test_ip4();
-            udp_watcher.bind(addr);
-            udp_watcher.close(||());
-            loop_.run();
-            loop_.close();
-        }
-    }
-
-    #[test]
-    fn udp_bind_close_ip6() {
-        do run_in_bare_thread() {
-            let mut loop_ = Loop::new();
-            let mut udp_watcher = { UdpWatcher::new(&mut loop_) };
-            let addr = next_test_ip6();
-            udp_watcher.bind(addr);
-            udp_watcher.close(||());
-            loop_.run();
-            loop_.close();
-        }
-    }
-
-    #[test]
-    fn listen_ip4() {
-        do run_in_bare_thread() {
-            static MAX: int = 10;
-            let mut loop_ = Loop::new();
-            let mut server_tcp_watcher = { TcpWatcher::new(&mut loop_) };
-            let addr = next_test_ip4();
-            server_tcp_watcher.bind(addr);
-            let loop_ = loop_;
-            rtdebug!("listening");
-            let mut stream = server_tcp_watcher.as_stream();
-            let res = do stream.listen |mut server_stream_watcher, status| {
-                rtdebug!("listened!");
-                assert!(status.is_none());
-                let mut loop_ = loop_;
-                let client_tcp_watcher = TcpWatcher::new(&mut loop_);
-                let mut client_tcp_watcher = client_tcp_watcher.as_stream();
-                server_stream_watcher.accept(client_tcp_watcher);
-                let count_cell = Cell::new(0);
-                let server_stream_watcher = server_stream_watcher;
-                rtdebug!("starting read");
-                let alloc: AllocCallback = |size| {
-                    vec_to_uv_buf(vec::from_elem(size, 0u8))
-                };
-                do client_tcp_watcher.read_start(alloc) |stream_watcher, nread, buf, status| {
-
-                    rtdebug!("i'm reading!");
-                    let buf = vec_from_uv_buf(buf);
-                    let mut count = count_cell.take();
-                    if status.is_none() {
-                        rtdebug!("got {} bytes", nread);
-                        let buf = buf.unwrap();
-                        for byte in buf.slice(0, nread as uint).iter() {
-                            assert!(*byte == count as u8);
-                            rtdebug!("{}", *byte as uint);
-                            count += 1;
-                        }
-                    } else {
-                        assert_eq!(count, MAX);
-                        do stream_watcher.close {
-                            server_stream_watcher.close(||());
-                        }
-                    }
-                    count_cell.put_back(count);
-                }
-            };
-
-            assert!(res.is_ok());
-
-            let client_thread = do Thread::start {
-                rtdebug!("starting client thread");
-                let mut loop_ = Loop::new();
-                let mut tcp_watcher = { TcpWatcher::new(&mut loop_) };
-                do tcp_watcher.connect(addr) |mut stream_watcher, status| {
-                    rtdebug!("connecting");
-                    assert!(status.is_none());
-                    let msg = ~[0, 1, 2, 3, 4, 5, 6 ,7 ,8, 9];
-                    let buf = slice_to_uv_buf(msg);
-                    let msg_cell = Cell::new(msg);
-                    do stream_watcher.write(buf) |stream_watcher, status| {
-                        rtdebug!("writing");
-                        assert!(status.is_none());
-                        let msg_cell = Cell::new(msg_cell.take());
-                        stream_watcher.close(||ignore(msg_cell.take()));
-                    }
-                }
-                loop_.run();
-                loop_.close();
-            };
-
-            let mut loop_ = loop_;
-            loop_.run();
-            loop_.close();
-            client_thread.join();
-        };
-    }
-
-    #[test]
-    fn listen_ip6() {
-        do run_in_bare_thread() {
-            static MAX: int = 10;
-            let mut loop_ = Loop::new();
-            let mut server_tcp_watcher = { TcpWatcher::new(&mut loop_) };
-            let addr = next_test_ip6();
-            server_tcp_watcher.bind(addr);
-            let loop_ = loop_;
-            rtdebug!("listening");
-            let mut stream = server_tcp_watcher.as_stream();
-            let res = do stream.listen |mut server_stream_watcher, status| {
-                rtdebug!("listened!");
-                assert!(status.is_none());
-                let mut loop_ = loop_;
-                let client_tcp_watcher = TcpWatcher::new(&mut loop_);
-                let mut client_tcp_watcher = client_tcp_watcher.as_stream();
-                server_stream_watcher.accept(client_tcp_watcher);
-                let count_cell = Cell::new(0);
-                let server_stream_watcher = server_stream_watcher;
-                rtdebug!("starting read");
-                let alloc: AllocCallback = |size| {
-                    vec_to_uv_buf(vec::from_elem(size, 0u8))
-                };
-                do client_tcp_watcher.read_start(alloc)
-                    |stream_watcher, nread, buf, status| {
-
-                    rtdebug!("i'm reading!");
-                    let buf = vec_from_uv_buf(buf);
-                    let mut count = count_cell.take();
-                    if status.is_none() {
-                        rtdebug!("got {} bytes", nread);
-                        let buf = buf.unwrap();
-                        let r = buf.slice(0, nread as uint);
-                        for byte in r.iter() {
-                            assert!(*byte == count as u8);
-                            rtdebug!("{}", *byte as uint);
-                            count += 1;
-                        }
-                    } else {
-                        assert_eq!(count, MAX);
-                        do stream_watcher.close {
-                            server_stream_watcher.close(||());
-                        }
-                    }
-                    count_cell.put_back(count);
-                }
-            };
-            assert!(res.is_ok());
-
-            let client_thread = do Thread::start {
-                rtdebug!("starting client thread");
-                let mut loop_ = Loop::new();
-                let mut tcp_watcher = { TcpWatcher::new(&mut loop_) };
-                do tcp_watcher.connect(addr) |mut stream_watcher, status| {
-                    rtdebug!("connecting");
-                    assert!(status.is_none());
-                    let msg = ~[0, 1, 2, 3, 4, 5, 6 ,7 ,8, 9];
-                    let buf = slice_to_uv_buf(msg);
-                    let msg_cell = Cell::new(msg);
-                    do stream_watcher.write(buf) |stream_watcher, status| {
-                        rtdebug!("writing");
-                        assert!(status.is_none());
-                        let msg_cell = Cell::new(msg_cell.take());
-                        stream_watcher.close(||ignore(msg_cell.take()));
-                    }
-                }
-                loop_.run();
-                loop_.close();
-            };
-
-            let mut loop_ = loop_;
-            loop_.run();
-            loop_.close();
-            client_thread.join();
-        }
-    }
-
-    #[test]
-    fn udp_recv_ip4() {
-        do run_in_bare_thread() {
-            static MAX: int = 10;
-            let mut loop_ = Loop::new();
-            let server_addr = next_test_ip4();
-            let client_addr = next_test_ip4();
-
-            let mut server = UdpWatcher::new(&loop_);
-            assert!(server.bind(server_addr).is_ok());
-
-            rtdebug!("starting read");
-            let alloc: AllocCallback = |size| {
-                vec_to_uv_buf(vec::from_elem(size, 0u8))
-            };
-
-            do server.recv_start(alloc) |mut server, nread, buf, src, flags, status| {
-                server.recv_stop();
-                rtdebug!("i'm reading!");
-                assert!(status.is_none());
-                assert_eq!(flags, 0);
-                assert_eq!(src, client_addr);
-
-                let buf = vec_from_uv_buf(buf);
-                let mut count = 0;
-                rtdebug!("got {} bytes", nread);
-
-                let buf = buf.unwrap();
-                for &byte in buf.slice(0, nread as uint).iter() {
-                    assert!(byte == count as u8);
-                    rtdebug!("{}", byte as uint);
-                    count += 1;
-                }
-                assert_eq!(count, MAX);
-
-                server.close(||{});
-            }
-
-            let thread = do Thread::start {
-                let mut loop_ = Loop::new();
-                let mut client = UdpWatcher::new(&loop_);
-                assert!(client.bind(client_addr).is_ok());
-                let msg = ~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
-                let buf = slice_to_uv_buf(msg);
-                do client.send(buf, server_addr) |client, status| {
-                    rtdebug!("writing");
-                    assert!(status.is_none());
-                    client.close(||{});
-                }
-
-                loop_.run();
-                loop_.close();
-            };
-
-            loop_.run();
-            loop_.close();
-            thread.join();
-        }
-    }
-
-    #[test]
-    fn udp_recv_ip6() {
-        do run_in_bare_thread() {
-            static MAX: int = 10;
-            let mut loop_ = Loop::new();
-            let server_addr = next_test_ip6();
-            let client_addr = next_test_ip6();
-
-            let mut server = UdpWatcher::new(&loop_);
-            assert!(server.bind(server_addr).is_ok());
-
-            rtdebug!("starting read");
-            let alloc: AllocCallback = |size| {
-                vec_to_uv_buf(vec::from_elem(size, 0u8))
-            };
-
-            do server.recv_start(alloc) |mut server, nread, buf, src, flags, status| {
-                server.recv_stop();
-                rtdebug!("i'm reading!");
-                assert!(status.is_none());
-                assert_eq!(flags, 0);
-                assert_eq!(src, client_addr);
-
-                let buf = vec_from_uv_buf(buf);
-                let mut count = 0;
-                rtdebug!("got {} bytes", nread);
-
-                let buf = buf.unwrap();
-                for &byte in buf.slice(0, nread as uint).iter() {
-                    assert!(byte == count as u8);
-                    rtdebug!("{}", byte as uint);
-                    count += 1;
-                }
-                assert_eq!(count, MAX);
-
-                server.close(||{});
-            }
-
-            let thread = do Thread::start {
-                let mut loop_ = Loop::new();
-                let mut client = UdpWatcher::new(&loop_);
-                assert!(client.bind(client_addr).is_ok());
-                let msg = ~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
-                let buf = slice_to_uv_buf(msg);
-                do client.send(buf, server_addr) |client, status| {
-                    rtdebug!("writing");
-                    assert!(status.is_none());
-                    client.close(||{});
-                }
-
-                loop_.run();
-                loop_.close();
-            };
-
-            loop_.run();
-            loop_.close();
-            thread.join();
-        }
-    }
-}
diff --git a/src/libstd/rt/uv/pipe.rs b/src/libstd/rt/uv/pipe.rs
deleted file mode 100644 (file)
index 74b9312..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2013 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 prelude::*;
-use libc;
-use c_str::CString;
-
-use rt::uv;
-use rt::uv::net;
-use rt::uv::uvll;
-
-pub struct Pipe(*uvll::uv_pipe_t);
-
-impl uv::Watcher for Pipe {}
-
-impl Pipe {
-    pub fn new(loop_: &uv::Loop, ipc: bool) -> Pipe {
-        unsafe {
-            let handle = uvll::malloc_handle(uvll::UV_NAMED_PIPE);
-            assert!(handle.is_not_null());
-            let ipc = ipc as libc::c_int;
-            assert_eq!(uvll::pipe_init(loop_.native_handle(), handle, ipc), 0);
-            let mut ret: Pipe =
-                    uv::NativeHandle::from_native_handle(handle);
-            ret.install_watcher_data();
-            ret
-        }
-    }
-
-    pub fn as_stream(&self) -> net::StreamWatcher {
-        net::StreamWatcher(**self as *uvll::uv_stream_t)
-    }
-
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn open(&mut self, file: libc::c_int) -> Result<(), uv::UvError> {
-        match unsafe { uvll::pipe_open(self.native_handle(), file) } {
-            0 => Ok(()),
-            n => Err(uv::UvError(n))
-        }
-    }
-
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn bind(&mut self, name: &CString) -> Result<(), uv::UvError> {
-        do name.with_ref |name| {
-            match unsafe { uvll::pipe_bind(self.native_handle(), name) } {
-                0 => Ok(()),
-                n => Err(uv::UvError(n))
-            }
-        }
-    }
-
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn connect(&mut self, name: &CString, cb: uv::ConnectionCallback) {
-        {
-            let data = self.get_watcher_data();
-            assert!(data.connect_cb.is_none());
-            data.connect_cb = Some(cb);
-        }
-
-        let connect = net::ConnectRequest::new();
-        let name = do name.with_ref |p| { p };
-
-        unsafe {
-            uvll::pipe_connect(connect.native_handle(),
-                               self.native_handle(),
-                               name,
-                               connect_cb)
-        }
-
-        extern "C" fn connect_cb(req: *uvll::uv_connect_t, status: libc::c_int) {
-            let connect_request: net::ConnectRequest =
-                    uv::NativeHandle::from_native_handle(req);
-            let mut stream_watcher = connect_request.stream();
-            connect_request.delete();
-
-            let cb = stream_watcher.get_watcher_data().connect_cb.take_unwrap();
-            let status = uv::status_to_maybe_uv_error(status);
-            cb(stream_watcher, status);
-        }
-    }
-
-}
-
-impl uv::NativeHandle<*uvll::uv_pipe_t> for Pipe {
-    fn from_native_handle(handle: *uvll::uv_pipe_t) -> Pipe {
-        Pipe(handle)
-    }
-    fn native_handle(&self) -> *uvll::uv_pipe_t {
-        match self { &Pipe(ptr) => ptr }
-    }
-}
diff --git a/src/libstd/rt/uv/process.rs b/src/libstd/rt/uv/process.rs
deleted file mode 100644 (file)
index f0d0afe..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright 2013 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 prelude::*;
-use cell::Cell;
-use libc;
-use ptr;
-use vec;
-
-use rt::io::process::*;
-use rt::uv;
-use rt::uv::uvio::{UvPipeStream, UvUnboundPipe};
-use rt::uv::uvll;
-
-/// A process wraps the handle of the underlying uv_process_t.
-pub struct Process(*uvll::uv_process_t);
-
-impl uv::Watcher for Process {}
-
-impl Process {
-    /// Creates a new process, ready to spawn inside an event loop
-    pub fn new() -> Process {
-        let handle = unsafe { uvll::malloc_handle(uvll::UV_PROCESS) };
-        assert!(handle.is_not_null());
-        let mut ret: Process = uv::NativeHandle::from_native_handle(handle);
-        ret.install_watcher_data();
-        return ret;
-    }
-
-    /// Spawn a new process inside the specified event loop.
-    ///
-    /// The `config` variable will be passed down to libuv, and the `exit_cb`
-    /// will be run only once, when the process exits.
-    ///
-    /// Returns either the corresponding process object or an error which
-    /// occurred.
-    pub fn spawn(&mut self, loop_: &uv::Loop, config: ProcessConfig,
-                 exit_cb: uv::ExitCallback)
-                    -> Result<~[Option<~UvPipeStream>], uv::UvError>
-    {
-        let cwd = config.cwd.map(|s| s.to_c_str());
-
-        extern fn on_exit(p: *uvll::uv_process_t,
-                          exit_status: libc::c_int,
-                          term_signal: libc::c_int) {
-            let mut p: Process = uv::NativeHandle::from_native_handle(p);
-            let err = match exit_status {
-                0 => None,
-                _ => uv::status_to_maybe_uv_error(-1)
-            };
-            p.get_watcher_data().exit_cb.take_unwrap()(p,
-                                                       exit_status as int,
-                                                       term_signal as int,
-                                                       err);
-        }
-
-        let io = config.io;
-        let mut stdio = vec::with_capacity::<uvll::uv_stdio_container_t>(io.len());
-        let mut ret_io = vec::with_capacity(io.len());
-        unsafe {
-            vec::raw::set_len(&mut stdio, io.len());
-            for (slot, other) in stdio.iter().zip(io.iter()) {
-                let io = set_stdio(slot as *uvll::uv_stdio_container_t, other,
-                                   loop_);
-                ret_io.push(io);
-            }
-        }
-
-        let exit_cb = Cell::new(exit_cb);
-        let ret_io = Cell::new(ret_io);
-        do with_argv(config.program, config.args) |argv| {
-            do with_env(config.env) |envp| {
-                let options = uvll::uv_process_options_t {
-                    exit_cb: on_exit,
-                    file: unsafe { *argv },
-                    args: argv,
-                    env: envp,
-                    cwd: match cwd {
-                        Some(ref cwd) => cwd.with_ref(|p| p),
-                        None => ptr::null(),
-                    },
-                    flags: 0,
-                    stdio_count: stdio.len() as libc::c_int,
-                    stdio: stdio.as_imm_buf(|p, _| p),
-                    uid: 0,
-                    gid: 0,
-                };
-
-                match unsafe {
-                    uvll::spawn(loop_.native_handle(), **self, options)
-                } {
-                    0 => {
-                        (*self).get_watcher_data().exit_cb = Some(exit_cb.take());
-                        Ok(ret_io.take())
-                    }
-                    err => Err(uv::UvError(err))
-                }
-            }
-        }
-    }
-
-    /// Sends a signal to this process.
-    ///
-    /// This is a wrapper around `uv_process_kill`
-    pub fn kill(&self, signum: int) -> Result<(), uv::UvError> {
-        match unsafe {
-            uvll::process_kill(self.native_handle(), signum as libc::c_int)
-        } {
-            0 => Ok(()),
-            err => Err(uv::UvError(err))
-        }
-    }
-
-    /// Returns the process id of a spawned process
-    pub fn pid(&self) -> libc::pid_t {
-        unsafe { uvll::process_pid(**self) as libc::pid_t }
-    }
-}
-
-unsafe fn set_stdio(dst: *uvll::uv_stdio_container_t,
-                    io: &StdioContainer,
-                    loop_: &uv::Loop) -> Option<~UvPipeStream> {
-    match *io {
-        Ignored => {
-            uvll::set_stdio_container_flags(dst, uvll::STDIO_IGNORE);
-            None
-        }
-        InheritFd(fd) => {
-            uvll::set_stdio_container_flags(dst, uvll::STDIO_INHERIT_FD);
-            uvll::set_stdio_container_fd(dst, fd);
-            None
-        }
-        CreatePipe(readable, writable) => {
-            let mut flags = uvll::STDIO_CREATE_PIPE as libc::c_int;
-            if readable {
-                flags |= uvll::STDIO_READABLE_PIPE as libc::c_int;
-            }
-            if writable {
-                flags |= uvll::STDIO_WRITABLE_PIPE as libc::c_int;
-            }
-            let pipe = UvUnboundPipe::new(loop_);
-            let handle = pipe.pipe.as_stream().native_handle();
-            uvll::set_stdio_container_flags(dst, flags);
-            uvll::set_stdio_container_stream(dst, handle);
-            Some(~UvPipeStream::new(pipe))
-        }
-    }
-}
-
-/// Converts the program and arguments to the argv array expected by libuv
-fn with_argv<T>(prog: &str, args: &[~str], f: &fn(**libc::c_char) -> T) -> T {
-    // First, allocation space to put all the C-strings (we need to have
-    // ownership of them somewhere
-    let mut c_strs = vec::with_capacity(args.len() + 1);
-    c_strs.push(prog.to_c_str());
-    for arg in args.iter() {
-        c_strs.push(arg.to_c_str());
-    }
-
-    // Next, create the char** array
-    let mut c_args = vec::with_capacity(c_strs.len() + 1);
-    for s in c_strs.iter() {
-        c_args.push(s.with_ref(|p| p));
-    }
-    c_args.push(ptr::null());
-    c_args.as_imm_buf(|buf, _| f(buf))
-}
-
-/// Converts the environment to the env array expected by libuv
-fn with_env<T>(env: Option<&[(~str, ~str)]>, f: &fn(**libc::c_char) -> T) -> T {
-    let env = match env {
-        Some(s) => s,
-        None => { return f(ptr::null()); }
-    };
-    // As with argv, create some temporary storage and then the actual array
-    let mut envp = vec::with_capacity(env.len());
-    for &(ref key, ref value) in env.iter() {
-        envp.push(format!("{}={}", *key, *value).to_c_str());
-    }
-    let mut c_envp = vec::with_capacity(envp.len() + 1);
-    for s in envp.iter() {
-        c_envp.push(s.with_ref(|p| p));
-    }
-    c_envp.push(ptr::null());
-    c_envp.as_imm_buf(|buf, _| f(buf))
-}
-
-impl uv::NativeHandle<*uvll::uv_process_t> for Process {
-    fn from_native_handle(handle: *uvll::uv_process_t) -> Process {
-        Process(handle)
-    }
-    fn native_handle(&self) -> *uvll::uv_process_t {
-        match self { &Process(ptr) => ptr }
-    }
-}
diff --git a/src/libstd/rt/uv/signal.rs b/src/libstd/rt/uv/signal.rs
deleted file mode 100644 (file)
index 3252c89..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2013 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 cast;
-use option::Some;
-use libc::c_int;
-use result::{Err, Ok, Result};
-use rt::io::signal::Signum;
-use rt::uv::{Loop, NativeHandle, SignalCallback, UvError, Watcher};
-use rt::uv::uvll;
-
-pub struct SignalWatcher(*uvll::uv_signal_t);
-
-impl Watcher for SignalWatcher { }
-
-impl SignalWatcher {
-    pub fn new(loop_: &mut Loop) -> SignalWatcher {
-        unsafe {
-            let handle = uvll::malloc_handle(uvll::UV_SIGNAL);
-            assert!(handle.is_not_null());
-            assert!(0 == uvll::signal_init(loop_.native_handle(), handle));
-            let mut watcher: SignalWatcher = NativeHandle::from_native_handle(handle);
-            watcher.install_watcher_data();
-            return watcher;
-        }
-    }
-
-    pub fn start(&mut self, signum: Signum, callback: SignalCallback)
-            -> Result<(), UvError>
-    {
-        return unsafe {
-            match uvll::signal_start(self.native_handle(), signal_cb,
-                                     signum as c_int) {
-                0 => {
-                    let data = self.get_watcher_data();
-                    data.signal_cb = Some(callback);
-                    Ok(())
-                }
-                n => Err(UvError(n)),
-            }
-        };
-
-        extern fn signal_cb(handle: *uvll::uv_signal_t, signum: c_int) {
-            let mut watcher: SignalWatcher = NativeHandle::from_native_handle(handle);
-            let data = watcher.get_watcher_data();
-            let cb = data.signal_cb.get_ref();
-            (*cb)(watcher, unsafe { cast::transmute(signum as int) });
-        }
-    }
-
-    pub fn stop(&mut self) {
-        unsafe {
-            uvll::signal_stop(self.native_handle());
-        }
-    }
-}
-
-impl NativeHandle<*uvll::uv_signal_t> for SignalWatcher {
-    fn from_native_handle(handle: *uvll::uv_signal_t) -> SignalWatcher {
-        SignalWatcher(handle)
-    }
-
-    fn native_handle(&self) -> *uvll::uv_signal_t {
-        match self { &SignalWatcher(ptr) => ptr }
-    }
-}
diff --git a/src/libstd/rt/uv/timer.rs b/src/libstd/rt/uv/timer.rs
deleted file mode 100644 (file)
index fb3c84d..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2013 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 libc::c_int;
-use option::Some;
-use rt::uv::uvll;
-use rt::uv::{Watcher, Loop, NativeHandle, TimerCallback};
-use rt::uv::status_to_maybe_uv_error;
-
-pub struct TimerWatcher(*uvll::uv_timer_t);
-impl Watcher for TimerWatcher { }
-
-impl TimerWatcher {
-    pub fn new(loop_: &mut Loop) -> TimerWatcher {
-        unsafe {
-            let handle = uvll::malloc_handle(uvll::UV_TIMER);
-            assert!(handle.is_not_null());
-            assert!(0 == uvll::timer_init(loop_.native_handle(), handle));
-            let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle);
-            watcher.install_watcher_data();
-            return watcher;
-        }
-    }
-
-    pub fn start(&mut self, timeout: u64, repeat: u64, cb: TimerCallback) {
-        {
-            let data = self.get_watcher_data();
-            data.timer_cb = Some(cb);
-        }
-
-        unsafe {
-            uvll::timer_start(self.native_handle(), timer_cb, timeout, repeat);
-        }
-
-        extern fn timer_cb(handle: *uvll::uv_timer_t, status: c_int) {
-            let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle);
-            let data = watcher.get_watcher_data();
-            let cb = data.timer_cb.get_ref();
-            let status = status_to_maybe_uv_error(status);
-            (*cb)(watcher, status);
-        }
-    }
-
-    pub fn stop(&mut self) {
-        unsafe {
-            uvll::timer_stop(self.native_handle());
-        }
-    }
-}
-
-impl NativeHandle<*uvll::uv_timer_t> for TimerWatcher {
-    fn from_native_handle(handle: *uvll::uv_timer_t) -> TimerWatcher {
-        TimerWatcher(handle)
-    }
-    fn native_handle(&self) -> *uvll::uv_idle_t {
-        match self { &TimerWatcher(ptr) => ptr }
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::*;
-    use rt::uv::Loop;
-    use unstable::run_in_bare_thread;
-
-    #[test]
-    fn smoke_test() {
-        do run_in_bare_thread {
-            let mut count = 0;
-            let count_ptr: *mut int = &mut count;
-            let mut loop_ = Loop::new();
-            let mut timer = TimerWatcher::new(&mut loop_);
-            do timer.start(10, 0) |timer, status| {
-                assert!(status.is_none());
-                unsafe { *count_ptr += 1 };
-                timer.close(||());
-            }
-            loop_.run();
-            loop_.close();
-            assert!(count == 1);
-        }
-    }
-
-    #[test]
-    fn start_twice() {
-        do run_in_bare_thread {
-            let mut count = 0;
-            let count_ptr: *mut int = &mut count;
-            let mut loop_ = Loop::new();
-            let mut timer = TimerWatcher::new(&mut loop_);
-            do timer.start(10, 0) |timer, status| {
-                let mut timer = timer;
-                assert!(status.is_none());
-                unsafe { *count_ptr += 1 };
-                do timer.start(10, 0) |timer, status| {
-                    assert!(status.is_none());
-                    unsafe { *count_ptr += 1 };
-                    timer.close(||());
-                }
-            }
-            loop_.run();
-            loop_.close();
-            assert!(count == 2);
-        }
-    }
-
-    #[test]
-    fn repeat_stop() {
-        do run_in_bare_thread {
-            let mut count = 0;
-            let count_ptr: *mut int = &mut count;
-            let mut loop_ = Loop::new();
-            let mut timer = TimerWatcher::new(&mut loop_);
-            do timer.start(1, 2) |timer, status| {
-                assert!(status.is_none());
-                unsafe {
-                    *count_ptr += 1;
-
-                    if *count_ptr == 10 {
-
-                        // Stop the timer and do something else
-                        let mut timer = timer;
-                        timer.stop();
-                        // Freeze timer so it can be captured
-                        let timer = timer;
-
-                        let mut loop_ = timer.event_loop();
-                        let mut timer2 = TimerWatcher::new(&mut loop_);
-                        do timer2.start(10, 0) |timer2, _| {
-
-                            *count_ptr += 1;
-
-                            timer2.close(||());
-
-                            // Restart the original timer
-                            let mut timer = timer;
-                            do timer.start(1, 0) |timer, _| {
-                                *count_ptr += 1;
-                                timer.close(||());
-                            }
-                        }
-                    }
-                };
-            }
-            loop_.run();
-            loop_.close();
-            assert!(count == 12);
-        }
-    }
-
-}
diff --git a/src/libstd/rt/uv/tty.rs b/src/libstd/rt/uv/tty.rs
deleted file mode 100644 (file)
index f44c5ae..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2013 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 prelude::*;
-use libc;
-
-use rt::uv;
-use rt::uv::net;
-use rt::uv::uvll;
-
-/// A process wraps the handle of the underlying uv_process_t.
-pub struct TTY(*uvll::uv_tty_t);
-
-impl uv::Watcher for TTY {}
-
-impl TTY {
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn new(loop_: &uv::Loop, fd: libc::c_int, readable: bool) ->
-            Result<TTY, uv::UvError>
-    {
-        let handle = unsafe { uvll::malloc_handle(uvll::UV_TTY) };
-        assert!(handle.is_not_null());
-
-        let ret = unsafe {
-            uvll::tty_init(loop_.native_handle(), handle, fd as libc::c_int,
-                           readable as libc::c_int)
-        };
-        match ret {
-            0 => {
-                let mut ret: TTY = uv::NativeHandle::from_native_handle(handle);
-                ret.install_watcher_data();
-                Ok(ret)
-            }
-            n => {
-                unsafe { uvll::free_handle(handle); }
-                Err(uv::UvError(n))
-            }
-        }
-    }
-
-    pub fn as_stream(&self) -> net::StreamWatcher {
-        net::StreamWatcher(**self as *uvll::uv_stream_t)
-    }
-
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn set_mode(&self, raw: bool) -> Result<(), uv::UvError> {
-        let raw = raw as libc::c_int;
-        match unsafe { uvll::tty_set_mode(self.native_handle(), raw) } {
-            0 => Ok(()),
-            n => Err(uv::UvError(n))
-        }
-    }
-
-    #[fixed_stack_segment] #[inline(never)] #[allow(unused_mut)]
-    pub fn get_winsize(&self) -> Result<(int, int), uv::UvError> {
-        let mut width: libc::c_int = 0;
-        let mut height: libc::c_int = 0;
-        let widthptr: *libc::c_int = &width;
-        let heightptr: *libc::c_int = &width;
-
-        match unsafe { uvll::tty_get_winsize(self.native_handle(),
-                                             widthptr, heightptr) } {
-            0 => Ok((width as int, height as int)),
-            n => Err(uv::UvError(n))
-        }
-    }
-}
-
-impl uv::NativeHandle<*uvll::uv_tty_t> for TTY {
-    fn from_native_handle(handle: *uvll::uv_tty_t) -> TTY {
-        TTY(handle)
-    }
-    fn native_handle(&self) -> *uvll::uv_tty_t {
-        match self { &TTY(ptr) => ptr }
-    }
-}
-
diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs
deleted file mode 100644 (file)
index 2d3ecbb..0000000
+++ /dev/null
@@ -1,2527 +0,0 @@
-// Copyright 2013 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 c_str::{ToCStr, CString};
-use cast::transmute;
-use cast;
-use cell::Cell;
-use clone::Clone;
-use comm::{SendDeferred, SharedChan, Port, PortOne, GenericChan};
-use libc::{c_int, c_uint, c_void, pid_t};
-use ops::Drop;
-use option::*;
-use ptr;
-use str;
-use result::*;
-use rt::io::IoError;
-use rt::io::net::ip::{SocketAddr, IpAddr};
-use rt::io::{standard_error, OtherIoError, SeekStyle, SeekSet, SeekCur, SeekEnd};
-use rt::io::process::ProcessConfig;
-use rt::kill::BlockedTask;
-use rt::local::Local;
-use rt::rtio::*;
-use rt::sched::{Scheduler, SchedHandle};
-use rt::tube::Tube;
-use rt::task::Task;
-use rt::uv::*;
-use rt::uv::idle::IdleWatcher;
-use rt::uv::net::{UvIpv4SocketAddr, UvIpv6SocketAddr};
-use rt::uv::addrinfo::{GetAddrInfoRequest, accum_addrinfo};
-use unstable::sync::Exclusive;
-use path::{GenericPath, Path};
-use libc::{lseek, off_t, O_CREAT, O_APPEND, O_TRUNC, O_RDWR, O_RDONLY, O_WRONLY,
-          S_IRUSR, S_IWUSR, S_IRWXU};
-use rt::io::{FileMode, FileAccess, OpenOrCreate, Open, Create,
-             CreateOrTruncate, Append, Truncate, Read, Write, ReadWrite,
-             FileStat};
-use rt::io::signal::Signum;
-use task;
-use ai = rt::io::net::addrinfo;
-
-#[cfg(test)] use container::Container;
-#[cfg(test)] use unstable::run_in_bare_thread;
-#[cfg(test)] use rt::test::{spawntask,
-                            next_test_ip4,
-                            run_in_mt_newsched_task};
-#[cfg(test)] use iter::{Iterator, range};
-#[cfg(test)] use rt::comm::oneshot;
-
-// XXX we should not be calling uvll functions in here.
-
-trait HomingIO {
-
-    fn home<'r>(&'r mut self) -> &'r mut SchedHandle;
-
-    /// This function will move tasks to run on their home I/O scheduler. Note
-    /// that this function does *not* pin the task to the I/O scheduler, but
-    /// rather it simply moves it to running on the I/O scheduler.
-    fn go_to_IO_home(&mut self) -> uint {
-        use rt::sched::RunOnce;
-
-        let current_sched_id = do Local::borrow |sched: &mut Scheduler| {
-            sched.sched_id()
-        };
-
-        // Only need to invoke a context switch if we're not on the right
-        // scheduler.
-        if current_sched_id != self.home().sched_id {
-            do task::unkillable { // FIXME(#8674)
-                let scheduler: ~Scheduler = Local::take();
-                do scheduler.deschedule_running_task_and_then |_, task| {
-                    /* FIXME(#8674) if the task was already killed then wake
-                     * will return None. In that case, the home pointer will
-                     * never be set.
-                     *
-                     * RESOLUTION IDEA: Since the task is dead, we should
-                     * just abort the IO action.
-                     */
-                    do task.wake().map |task| {
-                        self.home().send(RunOnce(task));
-                    };
-                }
-            }
-        }
-
-        self.home().sched_id
-    }
-
-    // XXX: dummy self parameter
-    fn restore_original_home(_: Option<Self>, io_home: uint) {
-        // It would truly be a sad day if we had moved off the home I/O
-        // scheduler while we were doing I/O.
-        assert_eq!(Local::borrow(|sched: &mut Scheduler| sched.sched_id()),
-                   io_home);
-
-        // If we were a homed task, then we must send ourselves back to the
-        // original scheduler. Otherwise, we can just return and keep running
-        if !Task::on_appropriate_sched() {
-            do task::unkillable { // FIXME(#8674)
-                let scheduler: ~Scheduler = Local::take();
-                do scheduler.deschedule_running_task_and_then |_, task| {
-                    do task.wake().map |task| {
-                        Scheduler::run_task(task);
-                    };
-                }
-            }
-        }
-    }
-
-    fn home_for_io<A>(&mut self, io: &fn(&mut Self) -> A) -> A {
-        let home = self.go_to_IO_home();
-        let a = io(self); // do IO
-        HomingIO::restore_original_home(None::<Self>, home);
-        a // return the result of the IO
-    }
-
-    fn home_for_io_consume<A>(mut self, io: &fn(Self) -> A) -> A {
-        let home = self.go_to_IO_home();
-        let a = io(self); // do IO
-        HomingIO::restore_original_home(None::<Self>, home);
-        a // return the result of the IO
-    }
-
-    fn home_for_io_with_sched<A>(&mut self, io_sched: &fn(&mut Self, ~Scheduler) -> A) -> A {
-        let home = self.go_to_IO_home();
-        let a = do task::unkillable { // FIXME(#8674)
-            let scheduler: ~Scheduler = Local::take();
-            io_sched(self, scheduler) // do IO and scheduling action
-        };
-        HomingIO::restore_original_home(None::<Self>, home);
-        a // return result of IO
-    }
-}
-
-// get a handle for the current scheduler
-macro_rules! get_handle_to_current_scheduler(
-    () => (do Local::borrow |sched: &mut Scheduler| { sched.make_handle() })
-)
-
-enum SocketNameKind {
-    TcpPeer,
-    Tcp,
-    Udp
-}
-
-fn socket_name<T, U: Watcher + NativeHandle<*T>>(sk: SocketNameKind,
-                                                 handle: U) -> Result<SocketAddr, IoError> {
-    let getsockname = match sk {
-        TcpPeer => uvll::tcp_getpeername,
-        Tcp     => uvll::tcp_getsockname,
-        Udp     => uvll::udp_getsockname,
-    };
-
-    // Allocate a sockaddr_storage
-    // since we don't know if it's ipv4 or ipv6
-    let r_addr = unsafe { uvll::malloc_sockaddr_storage() };
-
-    let r = unsafe {
-        getsockname(handle.native_handle() as *c_void, r_addr as *uvll::sockaddr_storage)
-    };
-
-    if r != 0 {
-        let status = status_to_maybe_uv_error(r);
-        return Err(uv_error_to_io_error(status.unwrap()));
-    }
-
-    let addr = unsafe {
-        if uvll::is_ip6_addr(r_addr as *uvll::sockaddr) {
-            net::uv_socket_addr_to_socket_addr(UvIpv6SocketAddr(r_addr as *uvll::sockaddr_in6))
-        } else {
-            net::uv_socket_addr_to_socket_addr(UvIpv4SocketAddr(r_addr as *uvll::sockaddr_in))
-        }
-    };
-
-    unsafe { uvll::free_sockaddr_storage(r_addr); }
-
-    Ok(addr)
-
-}
-
-// Obviously an Event Loop is always home.
-pub struct UvEventLoop {
-    priv uvio: UvIoFactory
-}
-
-impl UvEventLoop {
-    pub fn new() -> UvEventLoop {
-        UvEventLoop {
-            uvio: UvIoFactory(Loop::new())
-        }
-    }
-}
-
-impl Drop for UvEventLoop {
-    fn drop(&mut self) {
-        self.uvio.uv_loop().close();
-    }
-}
-
-impl EventLoop for UvEventLoop {
-    fn run(&mut self) {
-        self.uvio.uv_loop().run();
-    }
-
-    fn callback(&mut self, f: ~fn()) {
-        let mut idle_watcher =  IdleWatcher::new(self.uvio.uv_loop());
-        do idle_watcher.start |mut idle_watcher, status| {
-            assert!(status.is_none());
-            idle_watcher.stop();
-            idle_watcher.close(||());
-            f();
-        }
-    }
-
-    fn pausible_idle_callback(&mut self) -> ~PausibleIdleCallback {
-        let idle_watcher = IdleWatcher::new(self.uvio.uv_loop());
-        ~UvPausibleIdleCallback {
-            watcher: idle_watcher,
-            idle_flag: false,
-            closed: false
-        } as ~PausibleIdleCallback
-    }
-
-    fn remote_callback(&mut self, f: ~fn()) -> ~RemoteCallback {
-        ~UvRemoteCallback::new(self.uvio.uv_loop(), f) as ~RemoteCallback
-    }
-
-    fn io<'a>(&'a mut self, f: &fn(&'a mut IoFactory)) {
-        f(&mut self.uvio as &mut IoFactory)
-    }
-}
-
-#[cfg(not(stage0))]
-#[lang = "event_loop_factory"]
-pub extern "C" fn new_loop() -> ~EventLoop {
-    ~UvEventLoop::new() as ~EventLoop
-}
-
-pub struct UvPausibleIdleCallback {
-    priv watcher: IdleWatcher,
-    priv idle_flag: bool,
-    priv closed: bool
-}
-
-impl PausibleIdleCallback for UvPausibleIdleCallback {
-    #[inline]
-    fn start(&mut self, f: ~fn()) {
-        do self.watcher.start |_idle_watcher, _status| {
-            f();
-        };
-        self.idle_flag = true;
-    }
-    #[inline]
-    fn pause(&mut self) {
-        if self.idle_flag == true {
-            self.watcher.stop();
-            self.idle_flag = false;
-        }
-    }
-    #[inline]
-    fn resume(&mut self) {
-        if self.idle_flag == false {
-            self.watcher.restart();
-            self.idle_flag = true;
-        }
-    }
-    #[inline]
-    fn close(&mut self) {
-        self.pause();
-        if !self.closed {
-            self.closed = true;
-            self.watcher.close(||{});
-        }
-    }
-}
-
-#[test]
-fn test_callback_run_once() {
-    do run_in_bare_thread {
-        let mut event_loop = UvEventLoop::new();
-        let mut count = 0;
-        let count_ptr: *mut int = &mut count;
-        do event_loop.callback {
-            unsafe { *count_ptr += 1 }
-        }
-        event_loop.run();
-        assert_eq!(count, 1);
-    }
-}
-
-// The entire point of async is to call into a loop from other threads so it does not need to home.
-pub struct UvRemoteCallback {
-    // The uv async handle for triggering the callback
-    priv async: AsyncWatcher,
-    // A flag to tell the callback to exit, set from the dtor. This is
-    // almost never contested - only in rare races with the dtor.
-    priv exit_flag: Exclusive<bool>
-}
-
-impl UvRemoteCallback {
-    pub fn new(loop_: &mut Loop, f: ~fn()) -> UvRemoteCallback {
-        let exit_flag = Exclusive::new(false);
-        let exit_flag_clone = exit_flag.clone();
-        let async = do AsyncWatcher::new(loop_) |watcher, status| {
-            assert!(status.is_none());
-
-            // The synchronization logic here is subtle. To review,
-            // the uv async handle type promises that, after it is
-            // triggered the remote callback is definitely called at
-            // least once. UvRemoteCallback needs to maintain those
-            // semantics while also shutting down cleanly from the
-            // dtor. In our case that means that, when the
-            // UvRemoteCallback dtor calls `async.send()`, here `f` is
-            // always called later.
-
-            // In the dtor both the exit flag is set and the async
-            // callback fired under a lock.  Here, before calling `f`,
-            // we take the lock and check the flag. Because we are
-            // checking the flag before calling `f`, and the flag is
-            // set under the same lock as the send, then if the flag
-            // is set then we're guaranteed to call `f` after the
-            // final send.
-
-            // If the check was done after `f()` then there would be a
-            // period between that call and the check where the dtor
-            // could be called in the other thread, missing the final
-            // callback while still destroying the handle.
-
-            let should_exit = unsafe {
-                exit_flag_clone.with_imm(|&should_exit| should_exit)
-            };
-
-            f();
-
-            if should_exit {
-                watcher.close(||());
-            }
-
-        };
-        UvRemoteCallback {
-            async: async,
-            exit_flag: exit_flag
-        }
-    }
-}
-
-impl RemoteCallback for UvRemoteCallback {
-    fn fire(&mut self) { self.async.send() }
-}
-
-impl Drop for UvRemoteCallback {
-    fn drop(&mut self) {
-        unsafe {
-            let this: &mut UvRemoteCallback = cast::transmute_mut(self);
-            do this.exit_flag.with |should_exit| {
-                // NB: These two things need to happen atomically. Otherwise
-                // the event handler could wake up due to a *previous*
-                // signal and see the exit flag, destroying the handle
-                // before the final send.
-                *should_exit = true;
-                this.async.send();
-            }
-        }
-    }
-}
-
-#[cfg(test)]
-mod test_remote {
-    use cell::Cell;
-    use rt::test::*;
-    use rt::thread::Thread;
-    use rt::tube::Tube;
-    use rt::rtio::EventLoop;
-    use rt::local::Local;
-    use rt::sched::Scheduler;
-
-    #[test]
-    fn test_uv_remote() {
-        do run_in_mt_newsched_task {
-            let mut tube = Tube::new();
-            let tube_clone = tube.clone();
-            let remote_cell = Cell::new_empty();
-            do Local::borrow |sched: &mut Scheduler| {
-                let tube_clone = tube_clone.clone();
-                let tube_clone_cell = Cell::new(tube_clone);
-                let remote = do sched.event_loop.remote_callback {
-                    // This could be called multiple times
-                    if !tube_clone_cell.is_empty() {
-                        tube_clone_cell.take().send(1);
-                    }
-                };
-                remote_cell.put_back(remote);
-            }
-            let thread = do Thread::start {
-                remote_cell.take().fire();
-            };
-
-            assert!(tube.recv() == 1);
-            thread.join();
-        }
-    }
-}
-
-pub struct UvIoFactory(Loop);
-
-impl UvIoFactory {
-    pub fn uv_loop<'a>(&'a mut self) -> &'a mut Loop {
-        match self { &UvIoFactory(ref mut ptr) => ptr }
-    }
-}
-
-/// Helper for a variety of simple uv_fs_* functions that
-/// have no ret val
-fn uv_fs_helper(loop_: &mut Loop, path: &CString,
-                cb: ~fn(&mut FsRequest, &mut Loop, &CString,
-                        ~fn(&FsRequest, Option<UvError>)))
-        -> Result<(), IoError> {
-    let result_cell = Cell::new_empty();
-    let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
-    let path_cell = Cell::new(path);
-    do task::unkillable { // FIXME(#8674)
-        let scheduler: ~Scheduler = Local::take();
-        let mut new_req = FsRequest::new();
-        do scheduler.deschedule_running_task_and_then |_, task| {
-            let task_cell = Cell::new(task);
-            let path = path_cell.take();
-            do cb(&mut new_req, loop_, path) |_, err| {
-                let res = match err {
-                    None => Ok(()),
-                    Some(err) => Err(uv_error_to_io_error(err))
-                };
-                unsafe { (*result_cell_ptr).put_back(res); }
-                let scheduler: ~Scheduler = Local::take();
-                scheduler.resume_blocked_task_immediately(task_cell.take());
-            };
-        }
-    }
-    assert!(!result_cell.is_empty());
-    return result_cell.take();
-}
-
-impl IoFactory for UvIoFactory {
-    // Connect to an address and return a new stream
-    // NB: This blocks the task waiting on the connection.
-    // It would probably be better to return a future
-    fn tcp_connect(&mut self, addr: SocketAddr) -> Result<~RtioTcpStream, IoError> {
-        // Create a cell in the task to hold the result. We will fill
-        // the cell before resuming the task.
-        let result_cell = Cell::new_empty();
-        let result_cell_ptr: *Cell<Result<~RtioTcpStream, IoError>> = &result_cell;
-
-        // Block this task and take ownership, switch to scheduler context
-        do task::unkillable { // FIXME(#8674)
-            let scheduler: ~Scheduler = Local::take();
-            do scheduler.deschedule_running_task_and_then |_, task| {
-
-                let mut tcp = TcpWatcher::new(self.uv_loop());
-                let task_cell = Cell::new(task);
-
-                // Wait for a connection
-                do tcp.connect(addr) |stream, status| {
-                    match status {
-                        None => {
-                            let tcp = NativeHandle::from_native_handle(stream.native_handle());
-                            let home = get_handle_to_current_scheduler!();
-                            let res = Ok(~UvTcpStream { watcher: tcp, home: home }
-                                                as ~RtioTcpStream);
-
-                            // Store the stream in the task's stack
-                            unsafe { (*result_cell_ptr).put_back(res); }
-
-                            // Context switch
-                            let scheduler: ~Scheduler = Local::take();
-                            scheduler.resume_blocked_task_immediately(task_cell.take());
-                        }
-                        Some(_) => {
-                            let task_cell = Cell::new(task_cell.take());
-                            do stream.close {
-                                let res = Err(uv_error_to_io_error(status.unwrap()));
-                                unsafe { (*result_cell_ptr).put_back(res); }
-                                let scheduler: ~Scheduler = Local::take();
-                                scheduler.resume_blocked_task_immediately(task_cell.take());
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        assert!(!result_cell.is_empty());
-        return result_cell.take();
-    }
-
-    fn tcp_bind(&mut self, addr: SocketAddr) -> Result<~RtioTcpListener, IoError> {
-        let mut watcher = TcpWatcher::new(self.uv_loop());
-        match watcher.bind(addr) {
-            Ok(_) => {
-                let home = get_handle_to_current_scheduler!();
-                Ok(~UvTcpListener::new(watcher, home) as ~RtioTcpListener)
-            }
-            Err(uverr) => {
-                do task::unkillable { // FIXME(#8674)
-                    let scheduler: ~Scheduler = Local::take();
-                    do scheduler.deschedule_running_task_and_then |_, task| {
-                        let task_cell = Cell::new(task);
-                        do watcher.as_stream().close {
-                            let scheduler: ~Scheduler = Local::take();
-                            scheduler.resume_blocked_task_immediately(task_cell.take());
-                        }
-                    }
-                    Err(uv_error_to_io_error(uverr))
-                }
-            }
-        }
-    }
-
-    fn udp_bind(&mut self, addr: SocketAddr) -> Result<~RtioUdpSocket, IoError> {
-        let mut watcher = UdpWatcher::new(self.uv_loop());
-        match watcher.bind(addr) {
-            Ok(_) => {
-                let home = get_handle_to_current_scheduler!();
-                Ok(~UvUdpSocket { watcher: watcher, home: home } as ~RtioUdpSocket)
-            }
-            Err(uverr) => {
-                do task::unkillable { // FIXME(#8674)
-                    let scheduler: ~Scheduler = Local::take();
-                    do scheduler.deschedule_running_task_and_then |_, task| {
-                        let task_cell = Cell::new(task);
-                        do watcher.close {
-                            let scheduler: ~Scheduler = Local::take();
-                            scheduler.resume_blocked_task_immediately(task_cell.take());
-                        }
-                    }
-                    Err(uv_error_to_io_error(uverr))
-                }
-            }
-        }
-    }
-
-    fn timer_init(&mut self) -> Result<~RtioTimer, IoError> {
-        let watcher = TimerWatcher::new(self.uv_loop());
-        let home = get_handle_to_current_scheduler!();
-        Ok(~UvTimer::new(watcher, home) as ~RtioTimer)
-    }
-
-    fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior) -> ~RtioFileStream {
-        let loop_ = Loop {handle: self.uv_loop().native_handle()};
-        let home = get_handle_to_current_scheduler!();
-        ~UvFileStream::new(loop_, fd, close, home) as ~RtioFileStream
-    }
-
-    fn fs_open(&mut self, path: &CString, fm: FileMode, fa: FileAccess)
-        -> Result<~RtioFileStream, IoError> {
-        let mut flags = match fm {
-            Open => 0,
-            Create => O_CREAT,
-            OpenOrCreate => O_CREAT,
-            Append => O_APPEND,
-            Truncate => O_TRUNC,
-            CreateOrTruncate => O_TRUNC | O_CREAT
-        };
-        flags = match fa {
-            Read => flags | O_RDONLY,
-            Write => flags | O_WRONLY,
-            ReadWrite => flags | O_RDWR
-        };
-        let create_mode = match fm {
-            Create|OpenOrCreate|CreateOrTruncate =>
-                S_IRUSR | S_IWUSR,
-            _ => 0
-        };
-        let result_cell = Cell::new_empty();
-        let result_cell_ptr: *Cell<Result<~RtioFileStream,
-                                           IoError>> = &result_cell;
-        let path_cell = Cell::new(path);
-        do task::unkillable { // FIXME(#8674)
-            let scheduler: ~Scheduler = Local::take();
-            let open_req = file::FsRequest::new();
-            do scheduler.deschedule_running_task_and_then |_, task| {
-                let task_cell = Cell::new(task);
-                let path = path_cell.take();
-                do open_req.open(self.uv_loop(), path, flags as int, create_mode as int)
-                      |req,err| {
-                    if err.is_none() {
-                        let loop_ = Loop {handle: req.get_loop().native_handle()};
-                        let home = get_handle_to_current_scheduler!();
-                        let fd = req.get_result() as c_int;
-                        let fs = ~UvFileStream::new(
-                            loop_, fd, CloseSynchronously, home) as ~RtioFileStream;
-                        let res = Ok(fs);
-                        unsafe { (*result_cell_ptr).put_back(res); }
-                        let scheduler: ~Scheduler = Local::take();
-                        scheduler.resume_blocked_task_immediately(task_cell.take());
-                    } else {
-                        let res = Err(uv_error_to_io_error(err.unwrap()));
-                        unsafe { (*result_cell_ptr).put_back(res); }
-                        let scheduler: ~Scheduler = Local::take();
-                        scheduler.resume_blocked_task_immediately(task_cell.take());
-                    }
-                };
-            };
-        };
-        assert!(!result_cell.is_empty());
-        return result_cell.take();
-    }
-
-    fn fs_unlink(&mut self, path: &CString) -> Result<(), IoError> {
-        do uv_fs_helper(self.uv_loop(), path) |unlink_req, l, p, cb| {
-            do unlink_req.unlink(l, p) |req, err| {
-                cb(req, err)
-            };
-        }
-    }
-    fn fs_stat(&mut self, path: &CString) -> Result<FileStat, IoError> {
-        use str::StrSlice;
-        let result_cell = Cell::new_empty();
-        let result_cell_ptr: *Cell<Result<FileStat,
-                                           IoError>> = &result_cell;
-        let path_cell = Cell::new(path);
-        do task::unkillable { // FIXME(#8674)
-            let scheduler: ~Scheduler = Local::take();
-            let stat_req = file::FsRequest::new();
-            do scheduler.deschedule_running_task_and_then |_, task| {
-                let task_cell = Cell::new(task);
-                let path = path_cell.take();
-                // Don't pick up the null byte
-                let slice = path.as_bytes().slice(0, path.len());
-                let path_instance = Cell::new(Path::new(slice));
-                do stat_req.stat(self.uv_loop(), path) |req,err| {
-                    let res = match err {
-                        None => {
-                            let stat = req.get_stat();
-                            Ok(FileStat {
-                                path: path_instance.take(),
-                                is_file: stat.is_file(),
-                                is_dir: stat.is_dir(),
-                                device: stat.st_dev,
-                                mode: stat.st_mode,
-                                inode: stat.st_ino,
-                                size: stat.st_size,
-                                created: stat.st_ctim.tv_sec as u64,
-                                modified: stat.st_mtim.tv_sec as u64,
-                                accessed: stat.st_atim.tv_sec as u64
-                            })
-                        },
-                        Some(e) => {
-                            Err(uv_error_to_io_error(e))
-                        }
-                    };
-                    unsafe { (*result_cell_ptr).put_back(res); }
-                    let scheduler: ~Scheduler = Local::take();
-                    scheduler.resume_blocked_task_immediately(task_cell.take());
-                };
-            };
-        };
-        assert!(!result_cell.is_empty());
-        return result_cell.take();
-    }
-
-    fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
-                          hint: Option<ai::Hint>) -> Result<~[ai::Info], IoError> {
-        let result_cell = Cell::new_empty();
-        let result_cell_ptr: *Cell<Result<~[ai::Info], IoError>> = &result_cell;
-        let host_ptr: *Option<&str> = &host;
-        let servname_ptr: *Option<&str> = &servname;
-        let hint_ptr: *Option<ai::Hint> = &hint;
-        let addrinfo_req = GetAddrInfoRequest::new();
-        let addrinfo_req_cell = Cell::new(addrinfo_req);
-
-        do task::unkillable { // FIXME(#8674)
-            let scheduler: ~Scheduler = Local::take();
-            do scheduler.deschedule_running_task_and_then |_, task| {
-                let task_cell = Cell::new(task);
-                let mut addrinfo_req = addrinfo_req_cell.take();
-                unsafe {
-                    do addrinfo_req.getaddrinfo(self.uv_loop(),
-                                                *host_ptr, *servname_ptr,
-                                                *hint_ptr) |_, addrinfo, err| {
-                        let res = match err {
-                            None => Ok(accum_addrinfo(addrinfo)),
-                            Some(err) => Err(uv_error_to_io_error(err))
-                        };
-                        (*result_cell_ptr).put_back(res);
-                        let scheduler: ~Scheduler = Local::take();
-                        scheduler.resume_blocked_task_immediately(task_cell.take());
-                    }
-                }
-            }
-        }
-        addrinfo_req.delete();
-        assert!(!result_cell.is_empty());
-        return result_cell.take();
-    }
-    fn fs_mkdir(&mut self, path: &CString) -> Result<(), IoError> {
-        let mode = S_IRWXU as int;
-        do uv_fs_helper(self.uv_loop(), path) |mkdir_req, l, p, cb| {
-            do mkdir_req.mkdir(l, p, mode as int) |req, err| {
-                cb(req, err)
-            };
-        }
-    }
-    fn fs_rmdir(&mut self, path: &CString) -> Result<(), IoError> {
-        do uv_fs_helper(self.uv_loop(), path) |rmdir_req, l, p, cb| {
-            do rmdir_req.rmdir(l, p) |req, err| {
-                cb(req, err)
-            };
-        }
-    }
-    fn fs_readdir(&mut self, path: &CString, flags: c_int) ->
-        Result<~[Path], IoError> {
-        use str::StrSlice;
-        let result_cell = Cell::new_empty();
-        let result_cell_ptr: *Cell<Result<~[Path],
-                                           IoError>> = &result_cell;
-        let path_cell = Cell::new(path);
-        do task::unkillable { // FIXME(#8674)
-            let scheduler: ~Scheduler = Local::take();
-            let stat_req = file::FsRequest::new();
-            do scheduler.deschedule_running_task_and_then |_, task| {
-                let task_cell = Cell::new(task);
-                let path = path_cell.take();
-                // Don't pick up the null byte
-                let slice = path.as_bytes().slice(0, path.len());
-                let path_parent = Cell::new(Path::new(slice));
-                do stat_req.readdir(self.uv_loop(), path, flags) |req,err| {
-                    let parent = path_parent.take();
-                    let res = match err {
-                        None => {
-                            let mut paths = ~[];
-                            do req.each_path |rel_path| {
-                                let p = rel_path.as_bytes();
-                                paths.push(parent.join(p.slice_to(rel_path.len())));
-                            }
-                            Ok(paths)
-                        },
-                        Some(e) => {
-                            Err(uv_error_to_io_error(e))
-                        }
-                    };
-                    unsafe { (*result_cell_ptr).put_back(res); }
-                    let scheduler: ~Scheduler = Local::take();
-                    scheduler.resume_blocked_task_immediately(task_cell.take());
-                };
-            };
-        };
-        assert!(!result_cell.is_empty());
-        return result_cell.take();
-    }
-
-    fn spawn(&mut self, config: ProcessConfig)
-            -> Result<(~RtioProcess, ~[Option<~RtioPipe>]), IoError>
-    {
-        // Sadly, we must create the UvProcess before we actually call uv_spawn
-        // so that the exit_cb can close over it and notify it when the process
-        // has exited.
-        let mut ret = ~UvProcess {
-            process: Process::new(),
-            home: None,
-            exit_status: None,
-            term_signal: None,
-            exit_error: None,
-            descheduled: None,
-        };
-        let ret_ptr = unsafe {
-            *cast::transmute::<&~UvProcess, &*mut UvProcess>(&ret)
-        };
-
-        // The purpose of this exit callback is to record the data about the
-        // exit and then wake up the task which may be waiting for the process
-        // to exit. This is all performed in the current io-loop, and the
-        // implementation of UvProcess ensures that reading these fields always
-        // occurs on the current io-loop.
-        let exit_cb: ExitCallback = |_, exit_status, term_signal, error| {
-            unsafe {
-                assert!((*ret_ptr).exit_status.is_none());
-                (*ret_ptr).exit_status = Some(exit_status);
-                (*ret_ptr).term_signal = Some(term_signal);
-                (*ret_ptr).exit_error = error;
-                match (*ret_ptr).descheduled.take() {
-                    Some(task) => {
-                        let scheduler: ~Scheduler = Local::take();
-                        scheduler.resume_blocked_task_immediately(task);
-                    }
-                    None => {}
-                }
-            }
-        };
-
-        match ret.process.spawn(self.uv_loop(), config, exit_cb) {
-            Ok(io) => {
-                // Only now do we actually get a handle to this scheduler.
-                ret.home = Some(get_handle_to_current_scheduler!());
-                Ok((ret as ~RtioProcess,
-                    io.move_iter().map(|p| p.map(|p| p as ~RtioPipe)).collect()))
-            }
-            Err(uverr) => {
-                // We still need to close the process handle we created, but
-                // that's taken care for us in the destructor of UvProcess
-                Err(uv_error_to_io_error(uverr))
-            }
-        }
-    }
-
-    fn unix_bind(&mut self, path: &CString) ->
-        Result<~RtioUnixListener, IoError> {
-        let mut pipe = UvUnboundPipe::new(self.uv_loop());
-        match pipe.pipe.bind(path) {
-            Ok(()) => Ok(~UvUnixListener::new(pipe) as ~RtioUnixListener),
-            Err(e) => Err(uv_error_to_io_error(e)),
-        }
-    }
-
-    fn unix_connect(&mut self, path: &CString) -> Result<~RtioPipe, IoError> {
-        let pipe = UvUnboundPipe::new(self.uv_loop());
-        let mut rawpipe = pipe.pipe;
-
-        let result_cell = Cell::new_empty();
-        let result_cell_ptr: *Cell<Result<~RtioPipe, IoError>> = &result_cell;
-        let pipe_cell = Cell::new(pipe);
-        let pipe_cell_ptr: *Cell<UvUnboundPipe> = &pipe_cell;
-
-        let scheduler: ~Scheduler = Local::take();
-        do scheduler.deschedule_running_task_and_then |_, task| {
-            let task_cell = Cell::new(task);
-            do rawpipe.connect(path) |_stream, err| {
-                let res = match err {
-                    None => {
-                        let pipe = unsafe { (*pipe_cell_ptr).take() };
-                        Ok(~UvPipeStream::new(pipe) as ~RtioPipe)
-                    }
-                    Some(e) => Err(uv_error_to_io_error(e)),
-                };
-                unsafe { (*result_cell_ptr).put_back(res); }
-                let scheduler: ~Scheduler = Local::take();
-                scheduler.resume_blocked_task_immediately(task_cell.take());
-            }
-        }
-
-        assert!(!result_cell.is_empty());
-        return result_cell.take();
-    }
-
-    fn tty_open(&mut self, fd: c_int, readable: bool)
-            -> Result<~RtioTTY, IoError> {
-        match tty::TTY::new(self.uv_loop(), fd, readable) {
-            Ok(tty) => Ok(~UvTTY {
-                home: get_handle_to_current_scheduler!(),
-                tty: tty,
-                fd: fd,
-            } as ~RtioTTY),
-            Err(e) => Err(uv_error_to_io_error(e))
-        }
-    }
-
-    fn pipe_open(&mut self, fd: c_int) -> Result<~RtioPipe, IoError> {
-        let mut pipe = UvUnboundPipe::new(self.uv_loop());
-        match pipe.pipe.open(fd) {
-            Ok(()) => Ok(~UvPipeStream::new(pipe) as ~RtioPipe),
-            Err(e) => Err(uv_error_to_io_error(e))
-        }
-    }
-
-    fn signal(&mut self, signum: Signum, channel: SharedChan<Signum>)
-        -> Result<~RtioSignal, IoError> {
-        let watcher = SignalWatcher::new(self.uv_loop());
-        let home = get_handle_to_current_scheduler!();
-        let mut signal = ~UvSignal::new(watcher, home);
-        match signal.watcher.start(signum, |_, _| channel.send_deferred(signum)) {
-            Ok(()) => Ok(signal as ~RtioSignal),
-            Err(e) => Err(uv_error_to_io_error(e)),
-        }
-    }
-}
-
-pub struct UvTcpListener {
-    priv watcher : TcpWatcher,
-    priv home: SchedHandle,
-}
-
-impl HomingIO for UvTcpListener {
-    fn home<'r>(&'r mut self) -> &'r mut SchedHandle { &mut self.home }
-}
-
-impl UvTcpListener {
-    fn new(watcher: TcpWatcher, home: SchedHandle) -> UvTcpListener {
-        UvTcpListener { watcher: watcher, home: home }
-    }
-}
-
-impl Drop for UvTcpListener {
-    fn drop(&mut self) {
-        do self.home_for_io_with_sched |self_, scheduler| {
-            do scheduler.deschedule_running_task_and_then |_, task| {
-                let task = Cell::new(task);
-                do self_.watcher.as_stream().close {
-                    let scheduler: ~Scheduler = Local::take();
-                    scheduler.resume_blocked_task_immediately(task.take());
-                }
-            }
-        }
-    }
-}
-
-impl RtioSocket for UvTcpListener {
-    fn socket_name(&mut self) -> Result<SocketAddr, IoError> {
-        do self.home_for_io |self_| {
-            socket_name(Tcp, self_.watcher)
-        }
-    }
-}
-
-impl RtioTcpListener for UvTcpListener {
-    fn listen(~self) -> Result<~RtioTcpAcceptor, IoError> {
-        do self.home_for_io_consume |self_| {
-            let acceptor = ~UvTcpAcceptor::new(self_);
-            let incoming = Cell::new(acceptor.incoming.clone());
-            let mut stream = acceptor.listener.watcher.as_stream();
-            let res = do stream.listen |mut server, status| {
-                do incoming.with_mut_ref |incoming| {
-                    let inc = match status {
-                        Some(_) => Err(standard_error(OtherIoError)),
-                        None => {
-                            let inc = TcpWatcher::new(&server.event_loop());
-                            // first accept call in the callback guarenteed to succeed
-                            server.accept(inc.as_stream());
-                            let home = get_handle_to_current_scheduler!();
-                            Ok(~UvTcpStream { watcher: inc, home: home }
-                                    as ~RtioTcpStream)
-                        }
-                    };
-                    incoming.send(inc);
-                }
-            };
-            match res {
-                Ok(()) => Ok(acceptor as ~RtioTcpAcceptor),
-                Err(e) => Err(uv_error_to_io_error(e)),
-            }
-        }
-    }
-}
-
-pub struct UvTcpAcceptor {
-    priv listener: UvTcpListener,
-    priv incoming: Tube<Result<~RtioTcpStream, IoError>>,
-}
-
-impl HomingIO for UvTcpAcceptor {
-    fn home<'r>(&'r mut self) -> &'r mut SchedHandle { self.listener.home() }
-}
-
-impl UvTcpAcceptor {
-    fn new(listener: UvTcpListener) -> UvTcpAcceptor {
-        UvTcpAcceptor { listener: listener, incoming: Tube::new() }
-    }
-}
-
-impl RtioSocket for UvTcpAcceptor {
-    fn socket_name(&mut self) -> Result<SocketAddr, IoError> {
-        do self.home_for_io |self_| {
-            socket_name(Tcp, self_.listener.watcher)
-        }
-    }
-}
-
-fn accept_simultaneously(stream: StreamWatcher, a: int) -> Result<(), IoError> {
-    let r = unsafe {
-        uvll::tcp_simultaneous_accepts(stream.native_handle(), a as c_int)
-    };
-
-    match status_to_maybe_uv_error(r) {
-        Some(err) => Err(uv_error_to_io_error(err)),
-        None => Ok(())
-    }
-}
-
-impl RtioTcpAcceptor for UvTcpAcceptor {
-    fn accept(&mut self) -> Result<~RtioTcpStream, IoError> {
-        do self.home_for_io |self_| {
-            self_.incoming.recv()
-        }
-    }
-
-    fn accept_simultaneously(&mut self) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-            accept_simultaneously(self_.listener.watcher.as_stream(), 1)
-        }
-    }
-
-    fn dont_accept_simultaneously(&mut self) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-            accept_simultaneously(self_.listener.watcher.as_stream(), 0)
-        }
-    }
-}
-
-fn read_stream(mut watcher: StreamWatcher,
-               scheduler: ~Scheduler,
-               buf: &mut [u8]) -> Result<uint, IoError> {
-    let result_cell = Cell::new_empty();
-    let result_cell_ptr: *Cell<Result<uint, IoError>> = &result_cell;
-
-    let buf_ptr: *&mut [u8] = &buf;
-    do scheduler.deschedule_running_task_and_then |_sched, task| {
-        let task_cell = Cell::new(task);
-        // XXX: We shouldn't reallocate these callbacks every
-        // call to read
-        let alloc: AllocCallback = |_| unsafe {
-            slice_to_uv_buf(*buf_ptr)
-        };
-        do watcher.read_start(alloc) |mut watcher, nread, _buf, status| {
-
-            // Stop reading so that no read callbacks are
-            // triggered before the user calls `read` again.
-            // XXX: Is there a performance impact to calling
-            // stop here?
-            watcher.read_stop();
-
-            let result = if status.is_none() {
-                assert!(nread >= 0);
-                Ok(nread as uint)
-            } else {
-                Err(uv_error_to_io_error(status.unwrap()))
-            };
-
-            unsafe { (*result_cell_ptr).put_back(result); }
-
-            let scheduler: ~Scheduler = Local::take();
-            scheduler.resume_blocked_task_immediately(task_cell.take());
-        }
-    }
-
-    assert!(!result_cell.is_empty());
-    result_cell.take()
-}
-
-fn write_stream(mut watcher: StreamWatcher,
-                scheduler: ~Scheduler,
-                buf: &[u8]) -> Result<(), IoError> {
-    let result_cell = Cell::new_empty();
-    let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
-    let buf_ptr: *&[u8] = &buf;
-    do scheduler.deschedule_running_task_and_then |_, task| {
-        let task_cell = Cell::new(task);
-        let buf = unsafe { slice_to_uv_buf(*buf_ptr) };
-        do watcher.write(buf) |_watcher, status| {
-            let result = if status.is_none() {
-                Ok(())
-            } else {
-                Err(uv_error_to_io_error(status.unwrap()))
-            };
-
-            unsafe { (*result_cell_ptr).put_back(result); }
-
-            let scheduler: ~Scheduler = Local::take();
-            scheduler.resume_blocked_task_immediately(task_cell.take());
-        }
-    }
-
-    assert!(!result_cell.is_empty());
-    result_cell.take()
-}
-
-pub struct UvUnboundPipe {
-    pipe: Pipe,
-    priv home: SchedHandle,
-}
-
-impl UvUnboundPipe {
-    /// Creates a new unbound pipe homed to the current scheduler, placed on the
-    /// specified event loop
-    pub fn new(loop_: &Loop) -> UvUnboundPipe {
-        UvUnboundPipe {
-            pipe: Pipe::new(loop_, false),
-            home: get_handle_to_current_scheduler!(),
-        }
-    }
-}
-
-impl HomingIO for UvUnboundPipe {
-    fn home<'r>(&'r mut self) -> &'r mut SchedHandle { &mut self.home }
-}
-
-impl Drop for UvUnboundPipe {
-    fn drop(&mut self) {
-        do self.home_for_io |self_| {
-            let scheduler: ~Scheduler = Local::take();
-            do scheduler.deschedule_running_task_and_then |_, task| {
-                let task_cell = Cell::new(task);
-                do self_.pipe.close {
-                    let scheduler: ~Scheduler = Local::take();
-                    scheduler.resume_blocked_task_immediately(task_cell.take());
-                }
-            }
-        }
-    }
-}
-
-pub struct UvPipeStream {
-    priv inner: UvUnboundPipe,
-}
-
-impl UvPipeStream {
-    pub fn new(inner: UvUnboundPipe) -> UvPipeStream {
-        UvPipeStream { inner: inner }
-    }
-}
-
-impl RtioPipe for UvPipeStream {
-    fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
-        do self.inner.home_for_io_with_sched |self_, scheduler| {
-            read_stream(self_.pipe.as_stream(), scheduler, buf)
-        }
-    }
-    fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
-        do self.inner.home_for_io_with_sched |self_, scheduler| {
-            write_stream(self_.pipe.as_stream(), scheduler, buf)
-        }
-    }
-}
-
-pub struct UvTcpStream {
-    priv watcher: TcpWatcher,
-    priv home: SchedHandle,
-}
-
-impl HomingIO for UvTcpStream {
-    fn home<'r>(&'r mut self) -> &'r mut SchedHandle { &mut self.home }
-}
-
-impl Drop for UvTcpStream {
-    fn drop(&mut self) {
-        do self.home_for_io_with_sched |self_, scheduler| {
-            do scheduler.deschedule_running_task_and_then |_, task| {
-                let task_cell = Cell::new(task);
-                do self_.watcher.as_stream().close {
-                    let scheduler: ~Scheduler = Local::take();
-                    scheduler.resume_blocked_task_immediately(task_cell.take());
-                }
-            }
-        }
-    }
-}
-
-impl RtioSocket for UvTcpStream {
-    fn socket_name(&mut self) -> Result<SocketAddr, IoError> {
-        do self.home_for_io |self_| {
-            socket_name(Tcp, self_.watcher)
-        }
-    }
-}
-
-impl RtioTcpStream for UvTcpStream {
-    fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
-        do self.home_for_io_with_sched |self_, scheduler| {
-            read_stream(self_.watcher.as_stream(), scheduler, buf)
-        }
-    }
-
-    fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
-        do self.home_for_io_with_sched |self_, scheduler| {
-            write_stream(self_.watcher.as_stream(), scheduler, buf)
-        }
-    }
-
-    fn peer_name(&mut self) -> Result<SocketAddr, IoError> {
-        do self.home_for_io |self_| {
-            socket_name(TcpPeer, self_.watcher)
-        }
-    }
-
-    fn control_congestion(&mut self) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-            let r = unsafe { uvll::tcp_nodelay(self_.watcher.native_handle(), 0 as c_int) };
-
-            match status_to_maybe_uv_error(r) {
-                Some(err) => Err(uv_error_to_io_error(err)),
-                None => Ok(())
-            }
-        }
-    }
-
-    fn nodelay(&mut self) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-            let r = unsafe { uvll::tcp_nodelay(self_.watcher.native_handle(), 1 as c_int) };
-
-            match status_to_maybe_uv_error(r) {
-                Some(err) => Err(uv_error_to_io_error(err)),
-                None => Ok(())
-            }
-        }
-    }
-
-    fn keepalive(&mut self, delay_in_seconds: uint) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-            let r = unsafe {
-                uvll::tcp_keepalive(self_.watcher.native_handle(), 1 as c_int,
-                                    delay_in_seconds as c_uint)
-            };
-
-            match status_to_maybe_uv_error(r) {
-                Some(err) => Err(uv_error_to_io_error(err)),
-                None => Ok(())
-            }
-        }
-    }
-
-    fn letdie(&mut self) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-            let r = unsafe {
-                uvll::tcp_keepalive(self_.watcher.native_handle(), 0 as c_int, 0 as c_uint)
-            };
-
-            match status_to_maybe_uv_error(r) {
-                Some(err) => Err(uv_error_to_io_error(err)),
-                None => Ok(())
-            }
-        }
-    }
-}
-
-pub struct UvUdpSocket {
-    priv watcher: UdpWatcher,
-    priv home: SchedHandle,
-}
-
-impl HomingIO for UvUdpSocket {
-    fn home<'r>(&'r mut self) -> &'r mut SchedHandle { &mut self.home }
-}
-
-impl Drop for UvUdpSocket {
-    fn drop(&mut self) {
-        do self.home_for_io_with_sched |self_, scheduler| {
-            do scheduler.deschedule_running_task_and_then |_, task| {
-                let task_cell = Cell::new(task);
-                do self_.watcher.close {
-                    let scheduler: ~Scheduler = Local::take();
-                    scheduler.resume_blocked_task_immediately(task_cell.take());
-                }
-            }
-        }
-    }
-}
-
-impl RtioSocket for UvUdpSocket {
-    fn socket_name(&mut self) -> Result<SocketAddr, IoError> {
-        do self.home_for_io |self_| {
-            socket_name(Udp, self_.watcher)
-        }
-    }
-}
-
-impl RtioUdpSocket for UvUdpSocket {
-    fn recvfrom(&mut self, buf: &mut [u8]) -> Result<(uint, SocketAddr), IoError> {
-        do self.home_for_io_with_sched |self_, scheduler| {
-            let result_cell = Cell::new_empty();
-            let result_cell_ptr: *Cell<Result<(uint, SocketAddr), IoError>> = &result_cell;
-
-            let buf_ptr: *&mut [u8] = &buf;
-            do scheduler.deschedule_running_task_and_then |_, task| {
-                let task_cell = Cell::new(task);
-                let alloc: AllocCallback = |_| unsafe { slice_to_uv_buf(*buf_ptr) };
-                do self_.watcher.recv_start(alloc) |mut watcher, nread, _buf, addr, flags, status| {
-                    let _ = flags; // /XXX add handling for partials?
-
-                    watcher.recv_stop();
-
-                    let result = match status {
-                        None => {
-                            assert!(nread >= 0);
-                            Ok((nread as uint, addr))
-                        }
-                        Some(err) => Err(uv_error_to_io_error(err)),
-                    };
-
-                    unsafe { (*result_cell_ptr).put_back(result); }
-
-                    let scheduler: ~Scheduler = Local::take();
-                    scheduler.resume_blocked_task_immediately(task_cell.take());
-                }
-            }
-
-            assert!(!result_cell.is_empty());
-            result_cell.take()
-        }
-    }
-
-    fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> Result<(), IoError> {
-        do self.home_for_io_with_sched |self_, scheduler| {
-            let result_cell = Cell::new_empty();
-            let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
-            let buf_ptr: *&[u8] = &buf;
-            do scheduler.deschedule_running_task_and_then |_, task| {
-                let task_cell = Cell::new(task);
-                let buf = unsafe { slice_to_uv_buf(*buf_ptr) };
-                do self_.watcher.send(buf, dst) |_watcher, status| {
-
-                    let result = match status {
-                        None => Ok(()),
-                        Some(err) => Err(uv_error_to_io_error(err)),
-                    };
-
-                    unsafe { (*result_cell_ptr).put_back(result); }
-
-                    let scheduler: ~Scheduler = Local::take();
-                    scheduler.resume_blocked_task_immediately(task_cell.take());
-                }
-            }
-
-            assert!(!result_cell.is_empty());
-            result_cell.take()
-        }
-    }
-
-    fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-            let r = unsafe {
-                do multi.to_str().with_c_str |m_addr| {
-                    uvll::udp_set_membership(self_.watcher.native_handle(), m_addr,
-                                             ptr::null(), uvll::UV_JOIN_GROUP)
-                }
-            };
-
-            match status_to_maybe_uv_error(r) {
-                Some(err) => Err(uv_error_to_io_error(err)),
-                None => Ok(())
-            }
-        }
-    }
-
-    fn leave_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-            let r = unsafe {
-                do multi.to_str().with_c_str |m_addr| {
-                    uvll::udp_set_membership(self_.watcher.native_handle(), m_addr,
-                                             ptr::null(), uvll::UV_LEAVE_GROUP)
-                }
-            };
-
-            match status_to_maybe_uv_error(r) {
-                Some(err) => Err(uv_error_to_io_error(err)),
-                None => Ok(())
-            }
-        }
-    }
-
-    fn loop_multicast_locally(&mut self) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-
-            let r = unsafe {
-                uvll::udp_set_multicast_loop(self_.watcher.native_handle(), 1 as c_int)
-            };
-
-            match status_to_maybe_uv_error(r) {
-                Some(err) => Err(uv_error_to_io_error(err)),
-                None => Ok(())
-            }
-        }
-    }
-
-    fn dont_loop_multicast_locally(&mut self) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-
-            let r = unsafe {
-                uvll::udp_set_multicast_loop(self_.watcher.native_handle(), 0 as c_int)
-            };
-
-            match status_to_maybe_uv_error(r) {
-                Some(err) => Err(uv_error_to_io_error(err)),
-                None => Ok(())
-            }
-        }
-    }
-
-    fn multicast_time_to_live(&mut self, ttl: int) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-
-            let r = unsafe {
-                uvll::udp_set_multicast_ttl(self_.watcher.native_handle(), ttl as c_int)
-            };
-
-            match status_to_maybe_uv_error(r) {
-                Some(err) => Err(uv_error_to_io_error(err)),
-                None => Ok(())
-            }
-        }
-    }
-
-    fn time_to_live(&mut self, ttl: int) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-
-            let r = unsafe {
-                uvll::udp_set_ttl(self_.watcher.native_handle(), ttl as c_int)
-            };
-
-            match status_to_maybe_uv_error(r) {
-                Some(err) => Err(uv_error_to_io_error(err)),
-                None => Ok(())
-            }
-        }
-    }
-
-    fn hear_broadcasts(&mut self) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-
-            let r = unsafe {
-                uvll::udp_set_broadcast(self_.watcher.native_handle(), 1 as c_int)
-            };
-
-            match status_to_maybe_uv_error(r) {
-                Some(err) => Err(uv_error_to_io_error(err)),
-                None => Ok(())
-            }
-        }
-    }
-
-    fn ignore_broadcasts(&mut self) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-
-            let r = unsafe {
-                uvll::udp_set_broadcast(self_.watcher.native_handle(), 0 as c_int)
-            };
-
-            match status_to_maybe_uv_error(r) {
-                Some(err) => Err(uv_error_to_io_error(err)),
-                None => Ok(())
-            }
-        }
-    }
-}
-
-pub struct UvTimer {
-    priv watcher: timer::TimerWatcher,
-    priv home: SchedHandle,
-}
-
-impl HomingIO for UvTimer {
-    fn home<'r>(&'r mut self) -> &'r mut SchedHandle { &mut self.home }
-}
-
-impl UvTimer {
-    fn new(w: timer::TimerWatcher, home: SchedHandle) -> UvTimer {
-        UvTimer { watcher: w, home: home }
-    }
-}
-
-impl Drop for UvTimer {
-    fn drop(&mut self) {
-        do self.home_for_io_with_sched |self_, scheduler| {
-            rtdebug!("closing UvTimer");
-            do scheduler.deschedule_running_task_and_then |_, task| {
-                let task_cell = Cell::new(task);
-                do self_.watcher.close {
-                    let scheduler: ~Scheduler = Local::take();
-                    scheduler.resume_blocked_task_immediately(task_cell.take());
-                }
-            }
-        }
-    }
-}
-
-impl RtioTimer for UvTimer {
-    fn sleep(&mut self, msecs: u64) {
-        do self.home_for_io_with_sched |self_, scheduler| {
-            do scheduler.deschedule_running_task_and_then |_sched, task| {
-                rtdebug!("sleep: entered scheduler context");
-                let task_cell = Cell::new(task);
-                do self_.watcher.start(msecs, 0) |_, status| {
-                    assert!(status.is_none());
-                    let scheduler: ~Scheduler = Local::take();
-                    scheduler.resume_blocked_task_immediately(task_cell.take());
-                }
-            }
-            self_.watcher.stop();
-        }
-    }
-
-    fn oneshot(&mut self, msecs: u64) -> PortOne<()> {
-        use comm::oneshot;
-
-        let (port, chan) = oneshot();
-        let chan = Cell::new(chan);
-        do self.home_for_io |self_| {
-            let chan = Cell::new(chan.take());
-            do self_.watcher.start(msecs, 0) |_, status| {
-                assert!(status.is_none());
-                assert!(!chan.is_empty());
-                chan.take().send_deferred(());
-            }
-        }
-
-        return port;
-    }
-
-    fn period(&mut self, msecs: u64) -> Port<()> {
-        use comm::stream;
-
-        let (port, chan) = stream();
-        let chan = Cell::new(chan);
-        do self.home_for_io |self_| {
-            let chan = Cell::new(chan.take());
-            do self_.watcher.start(msecs, msecs) |_, status| {
-                assert!(status.is_none());
-                do chan.with_ref |chan| {
-                    chan.send_deferred(());
-                }
-            }
-        }
-
-        return port;
-    }
-}
-
-pub struct UvFileStream {
-    priv loop_: Loop,
-    priv fd: c_int,
-    priv close: CloseBehavior,
-    priv home: SchedHandle,
-}
-
-impl HomingIO for UvFileStream {
-    fn home<'r>(&'r mut self) -> &'r mut SchedHandle { &mut self.home }
-}
-
-impl UvFileStream {
-    fn new(loop_: Loop, fd: c_int, close: CloseBehavior,
-           home: SchedHandle) -> UvFileStream {
-        UvFileStream {
-            loop_: loop_,
-            fd: fd,
-            close: close,
-            home: home,
-        }
-    }
-    fn base_read(&mut self, buf: &mut [u8], offset: i64) -> Result<int, IoError> {
-        let result_cell = Cell::new_empty();
-        let result_cell_ptr: *Cell<Result<int, IoError>> = &result_cell;
-        let buf_ptr: *&mut [u8] = &buf;
-        do self.home_for_io_with_sched |self_, scheduler| {
-            do scheduler.deschedule_running_task_and_then |_, task| {
-                let buf = unsafe { slice_to_uv_buf(*buf_ptr) };
-                let task_cell = Cell::new(task);
-                let read_req = file::FsRequest::new();
-                do read_req.read(&self_.loop_, self_.fd, buf, offset) |req, uverr| {
-                    let res = match uverr  {
-                        None => Ok(req.get_result() as int),
-                        Some(err) => Err(uv_error_to_io_error(err))
-                    };
-                    unsafe { (*result_cell_ptr).put_back(res); }
-                    let scheduler: ~Scheduler = Local::take();
-                    scheduler.resume_blocked_task_immediately(task_cell.take());
-                }
-            }
-        }
-        result_cell.take()
-    }
-    fn base_write(&mut self, buf: &[u8], offset: i64) -> Result<(), IoError> {
-        let result_cell = Cell::new_empty();
-        let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
-        let buf_ptr: *&[u8] = &buf;
-        do self.home_for_io_with_sched |self_, scheduler| {
-            do scheduler.deschedule_running_task_and_then |_, task| {
-                let buf = unsafe { slice_to_uv_buf(*buf_ptr) };
-                let task_cell = Cell::new(task);
-                let write_req = file::FsRequest::new();
-                do write_req.write(&self_.loop_, self_.fd, buf, offset) |_, uverr| {
-                    let res = match uverr  {
-                        None => Ok(()),
-                        Some(err) => Err(uv_error_to_io_error(err))
-                    };
-                    unsafe { (*result_cell_ptr).put_back(res); }
-                    let scheduler: ~Scheduler = Local::take();
-                    scheduler.resume_blocked_task_immediately(task_cell.take());
-                }
-            }
-        }
-        result_cell.take()
-    }
-    fn seek_common(&mut self, pos: i64, whence: c_int) ->
-        Result<u64, IoError>{
-        #[fixed_stack_segment]; #[inline(never)];
-        unsafe {
-            match lseek(self.fd, pos as off_t, whence) {
-                -1 => {
-                    Err(IoError {
-                        kind: OtherIoError,
-                        desc: "Failed to lseek.",
-                        detail: None
-                    })
-                },
-                n => Ok(n as u64)
-            }
-        }
-    }
-}
-
-impl Drop for UvFileStream {
-    fn drop(&mut self) {
-        match self.close {
-            DontClose => {}
-            CloseAsynchronously => {
-                let close_req = file::FsRequest::new();
-                do close_req.close(&self.loop_, self.fd) |_,_| {}
-            }
-            CloseSynchronously => {
-                do self.home_for_io_with_sched |self_, scheduler| {
-                    do scheduler.deschedule_running_task_and_then |_, task| {
-                        let task_cell = Cell::new(task);
-                        let close_req = file::FsRequest::new();
-                        do close_req.close(&self_.loop_, self_.fd) |_,_| {
-                            let scheduler: ~Scheduler = Local::take();
-                            scheduler.resume_blocked_task_immediately(task_cell.take());
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-impl RtioFileStream for UvFileStream {
-    fn read(&mut self, buf: &mut [u8]) -> Result<int, IoError> {
-        self.base_read(buf, -1)
-    }
-    fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
-        self.base_write(buf, -1)
-    }
-    fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError> {
-        self.base_read(buf, offset as i64)
-    }
-    fn pwrite(&mut self, buf: &[u8], offset: u64) -> Result<(), IoError> {
-        self.base_write(buf, offset as i64)
-    }
-    fn seek(&mut self, pos: i64, whence: SeekStyle) -> Result<u64, IoError> {
-        use libc::{SEEK_SET, SEEK_CUR, SEEK_END};
-        let whence = match whence {
-            SeekSet => SEEK_SET,
-            SeekCur => SEEK_CUR,
-            SeekEnd => SEEK_END
-        };
-        self.seek_common(pos, whence)
-    }
-    fn tell(&self) -> Result<u64, IoError> {
-        use libc::SEEK_CUR;
-        // this is temporary
-        let self_ = unsafe { cast::transmute::<&UvFileStream, &mut UvFileStream>(self) };
-        self_.seek_common(0, SEEK_CUR)
-    }
-    fn flush(&mut self) -> Result<(), IoError> {
-        Ok(())
-    }
-}
-
-pub struct UvProcess {
-    priv process: process::Process,
-
-    // Sadly, this structure must be created before we return it, so in that
-    // brief interim the `home` is None.
-    priv home: Option<SchedHandle>,
-
-    // All None until the process exits (exit_error may stay None)
-    priv exit_status: Option<int>,
-    priv term_signal: Option<int>,
-    priv exit_error: Option<UvError>,
-
-    // Used to store which task to wake up from the exit_cb
-    priv descheduled: Option<BlockedTask>,
-}
-
-impl HomingIO for UvProcess {
-    fn home<'r>(&'r mut self) -> &'r mut SchedHandle { self.home.get_mut_ref() }
-}
-
-impl Drop for UvProcess {
-    fn drop(&mut self) {
-        let close = |self_: &mut UvProcess| {
-            let scheduler: ~Scheduler = Local::take();
-            do scheduler.deschedule_running_task_and_then |_, task| {
-                let task = Cell::new(task);
-                do self_.process.close {
-                    let scheduler: ~Scheduler = Local::take();
-                    scheduler.resume_blocked_task_immediately(task.take());
-                }
-            }
-        };
-
-        // If home is none, then this process never actually successfully
-        // spawned, so there's no need to switch event loops
-        if self.home.is_none() {
-            close(self)
-        } else {
-            self.home_for_io(close)
-        }
-    }
-}
-
-impl RtioProcess for UvProcess {
-    fn id(&self) -> pid_t {
-        self.process.pid()
-    }
-
-    fn kill(&mut self, signal: int) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-            match self_.process.kill(signal) {
-                Ok(()) => Ok(()),
-                Err(uverr) => Err(uv_error_to_io_error(uverr))
-            }
-        }
-    }
-
-    fn wait(&mut self) -> int {
-        // Make sure (on the home scheduler) that we have an exit status listed
-        do self.home_for_io |self_| {
-            match self_.exit_status {
-                Some(*) => {}
-                None => {
-                    // If there's no exit code previously listed, then the
-                    // process's exit callback has yet to be invoked. We just
-                    // need to deschedule ourselves and wait to be reawoken.
-                    let scheduler: ~Scheduler = Local::take();
-                    do scheduler.deschedule_running_task_and_then |_, task| {
-                        assert!(self_.descheduled.is_none());
-                        self_.descheduled = Some(task);
-                    }
-                    assert!(self_.exit_status.is_some());
-                }
-            }
-        }
-
-        self.exit_status.unwrap()
-    }
-}
-
-pub struct UvUnixListener {
-    priv inner: UvUnboundPipe
-}
-
-impl HomingIO for UvUnixListener {
-    fn home<'r>(&'r mut self) -> &'r mut SchedHandle { self.inner.home() }
-}
-
-impl UvUnixListener {
-    fn new(pipe: UvUnboundPipe) -> UvUnixListener {
-        UvUnixListener { inner: pipe }
-    }
-}
-
-impl RtioUnixListener for UvUnixListener {
-    fn listen(~self) -> Result<~RtioUnixAcceptor, IoError> {
-        do self.home_for_io_consume |self_| {
-            let acceptor = ~UvUnixAcceptor::new(self_);
-            let incoming = Cell::new(acceptor.incoming.clone());
-            let mut stream = acceptor.listener.inner.pipe.as_stream();
-            let res = do stream.listen |mut server, status| {
-                do incoming.with_mut_ref |incoming| {
-                    let inc = match status {
-                        Some(e) => Err(uv_error_to_io_error(e)),
-                        None => {
-                            let pipe = UvUnboundPipe::new(&server.event_loop());
-                            server.accept(pipe.pipe.as_stream());
-                            Ok(~UvPipeStream::new(pipe) as ~RtioPipe)
-                        }
-                    };
-                    incoming.send(inc);
-                }
-            };
-            match res {
-                Ok(()) => Ok(acceptor as ~RtioUnixAcceptor),
-                Err(e) => Err(uv_error_to_io_error(e)),
-            }
-        }
-    }
-}
-
-pub struct UvTTY {
-    tty: tty::TTY,
-    home: SchedHandle,
-    fd: c_int,
-}
-
-impl HomingIO for UvTTY {
-    fn home<'r>(&'r mut self) -> &'r mut SchedHandle { &mut self.home }
-}
-
-impl Drop for UvTTY {
-    fn drop(&mut self) {
-        // TTY handles are used for the logger in a task, so this destructor is
-        // run when a task is destroyed. When a task is being destroyed, a local
-        // scheduler isn't available, so we can't do the normal "take the
-        // scheduler and resume once close is done". Instead close operations on
-        // a TTY are asynchronous.
-        self.tty.close_async();
-    }
-}
-
-impl RtioTTY for UvTTY {
-    fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
-        do self.home_for_io_with_sched |self_, scheduler| {
-            read_stream(self_.tty.as_stream(), scheduler, buf)
-        }
-    }
-
-    fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
-        do self.home_for_io_with_sched |self_, scheduler| {
-            write_stream(self_.tty.as_stream(), scheduler, buf)
-        }
-    }
-
-    fn set_raw(&mut self, raw: bool) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-            match self_.tty.set_mode(raw) {
-                Ok(p) => Ok(p), Err(e) => Err(uv_error_to_io_error(e))
-            }
-        }
-    }
-
-    fn get_winsize(&mut self) -> Result<(int, int), IoError> {
-        do self.home_for_io |self_| {
-            match self_.tty.get_winsize() {
-                Ok(p) => Ok(p), Err(e) => Err(uv_error_to_io_error(e))
-            }
-        }
-    }
-
-    fn isatty(&self) -> bool {
-        unsafe { uvll::guess_handle(self.fd) == uvll::UV_TTY as c_int }
-    }
-}
-
-pub struct UvUnixAcceptor {
-    listener: UvUnixListener,
-    incoming: Tube<Result<~RtioPipe, IoError>>,
-}
-
-impl HomingIO for UvUnixAcceptor {
-    fn home<'r>(&'r mut self) -> &'r mut SchedHandle { self.listener.home() }
-}
-
-impl UvUnixAcceptor {
-    fn new(listener: UvUnixListener) -> UvUnixAcceptor {
-        UvUnixAcceptor { listener: listener, incoming: Tube::new() }
-    }
-}
-
-impl RtioUnixAcceptor for UvUnixAcceptor {
-    fn accept(&mut self) -> Result<~RtioPipe, IoError> {
-        do self.home_for_io |self_| {
-            self_.incoming.recv()
-        }
-    }
-
-    fn accept_simultaneously(&mut self) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-            accept_simultaneously(self_.listener.inner.pipe.as_stream(), 1)
-        }
-    }
-
-    fn dont_accept_simultaneously(&mut self) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
-            accept_simultaneously(self_.listener.inner.pipe.as_stream(), 0)
-        }
-    }
-}
-
-pub struct UvSignal {
-    watcher: signal::SignalWatcher,
-    home: SchedHandle,
-}
-
-impl HomingIO for UvSignal {
-    fn home<'r>(&'r mut self) -> &'r mut SchedHandle { &mut self.home }
-}
-
-impl UvSignal {
-    fn new(w: signal::SignalWatcher, home: SchedHandle) -> UvSignal {
-        UvSignal { watcher: w, home: home }
-    }
-}
-
-impl RtioSignal for UvSignal {}
-
-impl Drop for UvSignal {
-    fn drop(&mut self) {
-        do self.home_for_io_with_sched |self_, scheduler| {
-            rtdebug!("closing UvSignal");
-            do scheduler.deschedule_running_task_and_then |_, task| {
-                let task_cell = Cell::new(task);
-                do self_.watcher.close {
-                    let scheduler: ~Scheduler = Local::take();
-                    scheduler.resume_blocked_task_immediately(task_cell.take());
-                }
-            }
-        }
-    }
-}
-
-// this function is full of lies
-unsafe fn local_io() -> &'static mut IoFactory {
-    do Local::borrow |sched: &mut Scheduler| {
-        let mut io = None;
-        sched.event_loop.io(|i| io = Some(i));
-        cast::transmute(io.unwrap())
-    }
-}
-
-#[test]
-fn test_simple_io_no_connect() {
-    do run_in_mt_newsched_task {
-        unsafe {
-            let io = local_io();
-            let addr = next_test_ip4();
-            let maybe_chan = io.tcp_connect(addr);
-            assert!(maybe_chan.is_err());
-        }
-    }
-}
-
-#[test]
-fn test_simple_udp_io_bind_only() {
-    do run_in_mt_newsched_task {
-        unsafe {
-            let io = local_io();
-            let addr = next_test_ip4();
-            let maybe_socket = io.udp_bind(addr);
-            assert!(maybe_socket.is_ok());
-        }
-    }
-}
-
-#[test]
-fn test_simple_homed_udp_io_bind_then_move_task_then_home_and_close() {
-    use rt::sleeper_list::SleeperList;
-    use rt::work_queue::WorkQueue;
-    use rt::thread::Thread;
-    use rt::task::Task;
-    use rt::sched::{Shutdown, TaskFromFriend};
-    use rt::task::UnwindResult;
-    do run_in_bare_thread {
-        let sleepers = SleeperList::new();
-        let work_queue1 = WorkQueue::new();
-        let work_queue2 = WorkQueue::new();
-        let queues = ~[work_queue1.clone(), work_queue2.clone()];
-
-        let loop1 = ~UvEventLoop::new() as ~EventLoop;
-        let mut sched1 = ~Scheduler::new(loop1, work_queue1, queues.clone(),
-                                         sleepers.clone());
-        let loop2 = ~UvEventLoop::new() as ~EventLoop;
-        let mut sched2 = ~Scheduler::new(loop2, work_queue2, queues.clone(),
-                                         sleepers.clone());
-
-        let handle1 = Cell::new(sched1.make_handle());
-        let handle2 = Cell::new(sched2.make_handle());
-        let tasksFriendHandle = Cell::new(sched2.make_handle());
-
-        let on_exit: ~fn(UnwindResult) = |exit_status| {
-            handle1.take().send(Shutdown);
-            handle2.take().send(Shutdown);
-            rtassert!(exit_status.is_success());
-        };
-
-        let test_function: ~fn() = || {
-            let io = unsafe { local_io() };
-            let addr = next_test_ip4();
-            let maybe_socket = io.udp_bind(addr);
-            // this socket is bound to this event loop
-            assert!(maybe_socket.is_ok());
-
-            // block self on sched1
-            do task::unkillable { // FIXME(#8674)
-                let scheduler: ~Scheduler = Local::take();
-                do scheduler.deschedule_running_task_and_then |_, task| {
-                    // unblock task
-                    do task.wake().map |task| {
-                      // send self to sched2
-                      tasksFriendHandle.take().send(TaskFromFriend(task));
-                    };
-                    // sched1 should now sleep since it has nothing else to do
-                }
-            }
-            // sched2 will wake up and get the task
-            // as we do nothing else, the function ends and the socket goes out of scope
-            // sched2 will start to run the destructor
-            // the destructor will first block the task, set it's home as sched1, then enqueue it
-            // sched2 will dequeue the task, see that it has a home, and send it to sched1
-            // sched1 will wake up, exec the close function on the correct loop, and then we're done
-        };
-
-        let mut main_task = ~Task::new_root(&mut sched1.stack_pool, None, test_function);
-        main_task.death.on_exit = Some(on_exit);
-        let main_task = Cell::new(main_task);
-
-        let null_task = Cell::new(~do Task::new_root(&mut sched2.stack_pool, None) || {});
-
-        let sched1 = Cell::new(sched1);
-        let sched2 = Cell::new(sched2);
-
-        let thread1 = do Thread::start {
-            sched1.take().bootstrap(main_task.take());
-        };
-        let thread2 = do Thread::start {
-            sched2.take().bootstrap(null_task.take());
-        };
-
-        thread1.join();
-        thread2.join();
-    }
-}
-
-#[test]
-fn test_simple_homed_udp_io_bind_then_move_handle_then_home_and_close() {
-    use rt::sleeper_list::SleeperList;
-    use rt::work_queue::WorkQueue;
-    use rt::thread::Thread;
-    use rt::task::Task;
-    use rt::comm::oneshot;
-    use rt::sched::Shutdown;
-    use rt::task::UnwindResult;
-    do run_in_bare_thread {
-        let sleepers = SleeperList::new();
-        let work_queue1 = WorkQueue::new();
-        let work_queue2 = WorkQueue::new();
-        let queues = ~[work_queue1.clone(), work_queue2.clone()];
-
-        let loop1 = ~UvEventLoop::new() as ~EventLoop;
-        let mut sched1 = ~Scheduler::new(loop1, work_queue1, queues.clone(),
-                                         sleepers.clone());
-        let loop2 = ~UvEventLoop::new() as ~EventLoop;
-        let mut sched2 = ~Scheduler::new(loop2, work_queue2, queues.clone(),
-                                         sleepers.clone());
-
-        let handle1 = Cell::new(sched1.make_handle());
-        let handle2 = Cell::new(sched2.make_handle());
-
-        let (port, chan) = oneshot();
-        let port = Cell::new(port);
-        let chan = Cell::new(chan);
-
-        let body1: ~fn() = || {
-            let io = unsafe { local_io() };
-            let addr = next_test_ip4();
-            let socket = io.udp_bind(addr);
-            assert!(socket.is_ok());
-            chan.take().send(socket);
-        };
-
-        let body2: ~fn() = || {
-            let socket = port.take().recv();
-            assert!(socket.is_ok());
-            /* The socket goes out of scope and the destructor is called.
-             * The destructor:
-             *  - sends itself back to sched1
-             *  - frees the socket
-             *  - resets the home of the task to whatever it was previously
-             */
-        };
-
-        let on_exit: ~fn(UnwindResult) = |exit| {
-            handle1.take().send(Shutdown);
-            handle2.take().send(Shutdown);
-            rtassert!(exit.is_success());
-        };
-
-        let task1 = Cell::new(~Task::new_root(&mut sched1.stack_pool, None, body1));
-
-        let mut task2 = ~Task::new_root(&mut sched2.stack_pool, None, body2);
-        task2.death.on_exit = Some(on_exit);
-        let task2 = Cell::new(task2);
-
-        let sched1 = Cell::new(sched1);
-        let sched2 = Cell::new(sched2);
-
-        let thread1 = do Thread::start {
-            sched1.take().bootstrap(task1.take());
-        };
-        let thread2 = do Thread::start {
-            sched2.take().bootstrap(task2.take());
-        };
-
-        thread1.join();
-        thread2.join();
-    }
-}
-
-#[test]
-fn test_simple_tcp_server_and_client() {
-    do run_in_mt_newsched_task {
-        let addr = next_test_ip4();
-        let (port, chan) = oneshot();
-        let port = Cell::new(port);
-        let chan = Cell::new(chan);
-
-        // Start the server first so it's listening when we connect
-        do spawntask {
-            unsafe {
-                let io = local_io();
-                let listener = io.tcp_bind(addr).unwrap();
-                let mut acceptor = listener.listen().unwrap();
-                chan.take().send(());
-                let mut stream = acceptor.accept().unwrap();
-                let mut buf = [0, .. 2048];
-                let nread = stream.read(buf).unwrap();
-                assert_eq!(nread, 8);
-                for i in range(0u, nread) {
-                    rtdebug!("{}", buf[i]);
-                    assert_eq!(buf[i], i as u8);
-                }
-            }
-        }
-
-        do spawntask {
-            unsafe {
-                port.take().recv();
-                let io = local_io();
-                let mut stream = io.tcp_connect(addr).unwrap();
-                stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
-            }
-        }
-    }
-}
-
-#[test]
-fn test_simple_tcp_server_and_client_on_diff_threads() {
-    use rt::sleeper_list::SleeperList;
-    use rt::work_queue::WorkQueue;
-    use rt::thread::Thread;
-    use rt::task::Task;
-    use rt::sched::{Shutdown};
-    use rt::task::UnwindResult;
-    do run_in_bare_thread {
-        let sleepers = SleeperList::new();
-
-        let server_addr = next_test_ip4();
-        let client_addr = server_addr.clone();
-
-        let server_work_queue = WorkQueue::new();
-        let client_work_queue = WorkQueue::new();
-        let queues = ~[server_work_queue.clone(), client_work_queue.clone()];
-
-        let sloop = ~UvEventLoop::new() as ~EventLoop;
-        let mut server_sched = ~Scheduler::new(sloop, server_work_queue,
-                                               queues.clone(), sleepers.clone());
-        let cloop = ~UvEventLoop::new() as ~EventLoop;
-        let mut client_sched = ~Scheduler::new(cloop, client_work_queue,
-                                               queues.clone(), sleepers.clone());
-
-        let server_handle = Cell::new(server_sched.make_handle());
-        let client_handle = Cell::new(client_sched.make_handle());
-
-        let server_on_exit: ~fn(UnwindResult) = |exit_status| {
-            server_handle.take().send(Shutdown);
-            rtassert!(exit_status.is_success());
-        };
-
-        let client_on_exit: ~fn(UnwindResult) = |exit_status| {
-            client_handle.take().send(Shutdown);
-            rtassert!(exit_status.is_success());
-        };
-
-        let server_fn: ~fn() = || {
-            let io = unsafe { local_io() };
-            let listener = io.tcp_bind(server_addr).unwrap();
-            let mut acceptor = listener.listen().unwrap();
-            let mut stream = acceptor.accept().unwrap();
-            let mut buf = [0, .. 2048];
-            let nread = stream.read(buf).unwrap();
-            assert_eq!(nread, 8);
-            for i in range(0u, nread) {
-                assert_eq!(buf[i], i as u8);
-            }
-        };
-
-        let client_fn: ~fn() = || {
-            let io = unsafe { local_io() };
-            let mut stream = io.tcp_connect(client_addr);
-            while stream.is_err() {
-                stream = io.tcp_connect(client_addr);
-            }
-            stream.unwrap().write([0, 1, 2, 3, 4, 5, 6, 7]);
-        };
-
-        let mut server_task = ~Task::new_root(&mut server_sched.stack_pool, None, server_fn);
-        server_task.death.on_exit = Some(server_on_exit);
-        let server_task = Cell::new(server_task);
-
-        let mut client_task = ~Task::new_root(&mut client_sched.stack_pool, None, client_fn);
-        client_task.death.on_exit = Some(client_on_exit);
-        let client_task = Cell::new(client_task);
-
-        let server_sched = Cell::new(server_sched);
-        let client_sched = Cell::new(client_sched);
-
-        let server_thread = do Thread::start {
-            server_sched.take().bootstrap(server_task.take());
-        };
-        let client_thread = do Thread::start {
-            client_sched.take().bootstrap(client_task.take());
-        };
-
-        server_thread.join();
-        client_thread.join();
-    }
-}
-
-#[test]
-fn test_simple_udp_server_and_client() {
-    do run_in_mt_newsched_task {
-        let server_addr = next_test_ip4();
-        let client_addr = next_test_ip4();
-        let (port, chan) = oneshot();
-        let port = Cell::new(port);
-        let chan = Cell::new(chan);
-
-        do spawntask {
-            unsafe {
-                let io = local_io();
-                let mut server_socket = io.udp_bind(server_addr).unwrap();
-                chan.take().send(());
-                let mut buf = [0, .. 2048];
-                let (nread,src) = server_socket.recvfrom(buf).unwrap();
-                assert_eq!(nread, 8);
-                for i in range(0u, nread) {
-                    rtdebug!("{}", buf[i]);
-                    assert_eq!(buf[i], i as u8);
-                }
-                assert_eq!(src, client_addr);
-            }
-        }
-
-        do spawntask {
-            unsafe {
-                let io = local_io();
-                let mut client_socket = io.udp_bind(client_addr).unwrap();
-                port.take().recv();
-                client_socket.sendto([0, 1, 2, 3, 4, 5, 6, 7], server_addr);
-            }
-        }
-    }
-}
-
-#[test] #[ignore(reason = "busted")]
-fn test_read_and_block() {
-    do run_in_mt_newsched_task {
-        let addr = next_test_ip4();
-        let (port, chan) = oneshot();
-        let port = Cell::new(port);
-        let chan = Cell::new(chan);
-
-        do spawntask {
-            let io = unsafe { local_io() };
-            let listener = io.tcp_bind(addr).unwrap();
-            let mut acceptor = listener.listen().unwrap();
-            chan.take().send(());
-            let mut stream = acceptor.accept().unwrap();
-            let mut buf = [0, .. 2048];
-
-            let expected = 32;
-            let mut current = 0;
-            let mut reads = 0;
-
-            while current < expected {
-                let nread = stream.read(buf).unwrap();
-                for i in range(0u, nread) {
-                    let val = buf[i] as uint;
-                    assert_eq!(val, current % 8);
-                    current += 1;
-                }
-                reads += 1;
-
-                do task::unkillable { // FIXME(#8674)
-                    let scheduler: ~Scheduler = Local::take();
-                    // Yield to the other task in hopes that it
-                    // will trigger a read callback while we are
-                    // not ready for it
-                    do scheduler.deschedule_running_task_and_then |sched, task| {
-                        let task = Cell::new(task);
-                        sched.enqueue_blocked_task(task.take());
-                    }
-                }
-            }
-
-            // Make sure we had multiple reads
-            assert!(reads > 1);
-        }
-
-        do spawntask {
-            unsafe {
-                port.take().recv();
-                let io = local_io();
-                let mut stream = io.tcp_connect(addr).unwrap();
-                stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
-                stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
-                stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
-                stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
-            }
-        }
-
-    }
-}
-
-#[test]
-fn test_read_read_read() {
-    do run_in_mt_newsched_task {
-        let addr = next_test_ip4();
-        static MAX: uint = 500000;
-        let (port, chan) = oneshot();
-        let port = Cell::new(port);
-        let chan = Cell::new(chan);
-
-        do spawntask {
-            unsafe {
-                let io = local_io();
-                let listener = io.tcp_bind(addr).unwrap();
-                let mut acceptor = listener.listen().unwrap();
-                chan.take().send(());
-                let mut stream = acceptor.accept().unwrap();
-                let buf = [1, .. 2048];
-                let mut total_bytes_written = 0;
-                while total_bytes_written < MAX {
-                    stream.write(buf);
-                    total_bytes_written += buf.len();
-                }
-            }
-        }
-
-        do spawntask {
-            unsafe {
-                port.take().recv();
-                let io = local_io();
-                let mut stream = io.tcp_connect(addr).unwrap();
-                let mut buf = [0, .. 2048];
-                let mut total_bytes_read = 0;
-                while total_bytes_read < MAX {
-                    let nread = stream.read(buf).unwrap();
-                    rtdebug!("read {} bytes", nread);
-                    total_bytes_read += nread;
-                    for i in range(0u, nread) {
-                        assert_eq!(buf[i], 1);
-                    }
-                }
-                rtdebug!("read {} bytes total", total_bytes_read);
-            }
-        }
-    }
-}
-
-#[test]
-#[ignore(cfg(windows))] // FIXME(#10102) the server never sees the second send
-fn test_udp_twice() {
-    do run_in_mt_newsched_task {
-        let server_addr = next_test_ip4();
-        let client_addr = next_test_ip4();
-        let (port, chan) = oneshot();
-        let port = Cell::new(port);
-        let chan = Cell::new(chan);
-
-        do spawntask {
-            unsafe {
-                let io = local_io();
-                let mut client = io.udp_bind(client_addr).unwrap();
-                port.take().recv();
-                assert!(client.sendto([1], server_addr).is_ok());
-                assert!(client.sendto([2], server_addr).is_ok());
-            }
-        }
-
-        do spawntask {
-            unsafe {
-                let io = local_io();
-                let mut server = io.udp_bind(server_addr).unwrap();
-                chan.take().send(());
-                let mut buf1 = [0];
-                let mut buf2 = [0];
-                let (nread1, src1) = server.recvfrom(buf1).unwrap();
-                let (nread2, src2) = server.recvfrom(buf2).unwrap();
-                assert_eq!(nread1, 1);
-                assert_eq!(nread2, 1);
-                assert_eq!(src1, client_addr);
-                assert_eq!(src2, client_addr);
-                assert_eq!(buf1[0], 1);
-                assert_eq!(buf2[0], 2);
-            }
-        }
-    }
-}
-
-#[test]
-fn test_udp_many_read() {
-    do run_in_mt_newsched_task {
-        let server_out_addr = next_test_ip4();
-        let server_in_addr = next_test_ip4();
-        let client_out_addr = next_test_ip4();
-        let client_in_addr = next_test_ip4();
-        static MAX: uint = 500_000;
-
-        let (p1, c1) = oneshot();
-        let (p2, c2) = oneshot();
-
-        let first = Cell::new((p1, c2));
-        let second = Cell::new((p2, c1));
-
-        do spawntask {
-            unsafe {
-                let io = local_io();
-                let mut server_out = io.udp_bind(server_out_addr).unwrap();
-                let mut server_in = io.udp_bind(server_in_addr).unwrap();
-                let (port, chan) = first.take();
-                chan.send(());
-                port.recv();
-                let msg = [1, .. 2048];
-                let mut total_bytes_sent = 0;
-                let mut buf = [1];
-                while buf[0] == 1 {
-                    // send more data
-                    assert!(server_out.sendto(msg, client_in_addr).is_ok());
-                    total_bytes_sent += msg.len();
-                    // check if the client has received enough
-                    let res = server_in.recvfrom(buf);
-                    assert!(res.is_ok());
-                    let (nread, src) = res.unwrap();
-                    assert_eq!(nread, 1);
-                    assert_eq!(src, client_out_addr);
-                }
-                assert!(total_bytes_sent >= MAX);
-            }
-        }
-
-        do spawntask {
-            unsafe {
-                let io = local_io();
-                let mut client_out = io.udp_bind(client_out_addr).unwrap();
-                let mut client_in = io.udp_bind(client_in_addr).unwrap();
-                let (port, chan) = second.take();
-                port.recv();
-                chan.send(());
-                let mut total_bytes_recv = 0;
-                let mut buf = [0, .. 2048];
-                while total_bytes_recv < MAX {
-                    // ask for more
-                    assert!(client_out.sendto([1], server_in_addr).is_ok());
-                    // wait for data
-                    let res = client_in.recvfrom(buf);
-                    assert!(res.is_ok());
-                    let (nread, src) = res.unwrap();
-                    assert_eq!(src, server_out_addr);
-                    total_bytes_recv += nread;
-                    for i in range(0u, nread) {
-                        assert_eq!(buf[i], 1);
-                    }
-                }
-                // tell the server we're done
-                assert!(client_out.sendto([0], server_in_addr).is_ok());
-            }
-        }
-    }
-}
-
-#[test]
-fn test_timer_sleep_simple() {
-    do run_in_mt_newsched_task {
-        unsafe {
-            let io = local_io();
-            let timer = io.timer_init();
-            do timer.map_move |mut t| { t.sleep(1) };
-        }
-    }
-}
-
-fn file_test_uvio_full_simple_impl() {
-    use str::StrSlice; // why does this have to be explicitly imported to work?
-                       // compiler was complaining about no trait for str that
-                       // does .as_bytes() ..
-    use rt::io::{Open, Create, ReadWrite, Read};
-    unsafe {
-        let io = local_io();
-        let write_val = "hello uvio!";
-        let path = "./tmp/file_test_uvio_full.txt";
-        {
-            let create_fm = Create;
-            let create_fa = ReadWrite;
-            let mut fd = io.fs_open(&path.to_c_str(), create_fm, create_fa).unwrap();
-            let write_buf = write_val.as_bytes();
-            fd.write(write_buf);
-        }
-        {
-            let ro_fm = Open;
-            let ro_fa = Read;
-            let mut fd = io.fs_open(&path.to_c_str(), ro_fm, ro_fa).unwrap();
-            let mut read_vec = [0, .. 1028];
-            let nread = fd.read(read_vec).unwrap();
-            let read_val = str::from_utf8(read_vec.slice(0, nread as uint));
-            assert!(read_val == write_val.to_owned());
-        }
-        io.fs_unlink(&path.to_c_str());
-    }
-}
-
-#[test]
-fn file_test_uvio_full_simple() {
-    do run_in_mt_newsched_task {
-        file_test_uvio_full_simple_impl();
-    }
-}
-
-fn uvio_naive_print(input: &str) {
-    use str::StrSlice;
-    unsafe {
-        use libc::{STDOUT_FILENO};
-        let io = local_io();
-        {
-            let mut fd = io.fs_from_raw_fd(STDOUT_FILENO, DontClose);
-            let write_buf = input.as_bytes();
-            fd.write(write_buf);
-        }
-    }
-}
-
-#[test]
-fn file_test_uvio_write_to_stdout() {
-    do run_in_mt_newsched_task {
-        uvio_naive_print("jubilation\n");
-    }
-}
diff --git a/src/libstd/rt/uv/uvll.rs b/src/libstd/rt/uv/uvll.rs
deleted file mode 100644 (file)
index 2964eb9..0000000
+++ /dev/null
@@ -1,1176 +0,0 @@
-// 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.
-
-/*!
- * Low-level bindings to the libuv library.
- *
- * This module contains a set of direct, 'bare-metal' wrappers around
- * the libuv C-API.
- *
- * We're not bothering yet to redefine uv's structs as Rust structs
- * because they are quite large and change often between versions.
- * The maintenance burden is just too high. Instead we use the uv's
- * `uv_handle_size` and `uv_req_size` to find the correct size of the
- * structs and allocate them on the heap. This can be revisited later.
- *
- * There are also a collection of helper functions to ease interacting
- * with the low-level API.
- *
- * As new functionality, existent in uv.h, is added to the rust stdlib,
- * the mappings should be added in this module.
- */
-
-#[allow(non_camel_case_types)]; // C types
-
-use c_str::ToCStr;
-use libc::{size_t, c_int, c_uint, c_void, c_char, uintptr_t};
-use libc::ssize_t;
-use libc::{malloc, free};
-use libc;
-use prelude::*;
-use ptr;
-use vec;
-
-pub use self::errors::*;
-
-pub static OK: c_int = 0;
-pub static EOF: c_int = -4095;
-pub static UNKNOWN: c_int = -4094;
-
-// uv-errno.h redefines error codes for windows, but not for unix...
-
-#[cfg(windows)]
-pub mod errors {
-    use libc::c_int;
-
-    pub static EACCES: c_int = -4093;
-    pub static ECONNREFUSED: c_int = -4079;
-    pub static ECONNRESET: c_int = -4078;
-    pub static ENOTCONN: c_int = -4054;
-    pub static EPIPE: c_int = -4048;
-    pub static ECONNABORTED: c_int = -4080;
-}
-#[cfg(not(windows))]
-pub mod errors {
-    use libc;
-    use libc::c_int;
-
-    pub static EACCES: c_int = -libc::EACCES;
-    pub static ECONNREFUSED: c_int = -libc::ECONNREFUSED;
-    pub static ECONNRESET: c_int = -libc::ECONNRESET;
-    pub static ENOTCONN: c_int = -libc::ENOTCONN;
-    pub static EPIPE: c_int = -libc::EPIPE;
-    pub static ECONNABORTED: c_int = -libc::ECONNABORTED;
-}
-
-pub static PROCESS_SETUID: c_int = 1 << 0;
-pub static PROCESS_SETGID: c_int = 1 << 1;
-pub static PROCESS_WINDOWS_VERBATIM_ARGUMENTS: c_int = 1 << 2;
-pub static PROCESS_DETACHED: c_int = 1 << 3;
-pub static PROCESS_WINDOWS_HIDE: c_int = 1 << 4;
-
-pub static STDIO_IGNORE: c_int = 0x00;
-pub static STDIO_CREATE_PIPE: c_int = 0x01;
-pub static STDIO_INHERIT_FD: c_int = 0x02;
-pub static STDIO_INHERIT_STREAM: c_int = 0x04;
-pub static STDIO_READABLE_PIPE: c_int = 0x10;
-pub static STDIO_WRITABLE_PIPE: c_int = 0x20;
-
-// see libuv/include/uv-unix.h
-#[cfg(unix)]
-pub struct uv_buf_t {
-    base: *u8,
-    len: libc::size_t,
-}
-
-// see libuv/include/uv-win.h
-#[cfg(windows)]
-pub struct uv_buf_t {
-    len: u32,
-    base: *u8,
-}
-
-pub struct uv_process_options_t {
-    exit_cb: uv_exit_cb,
-    file: *libc::c_char,
-    args: **libc::c_char,
-    env: **libc::c_char,
-    cwd: *libc::c_char,
-    flags: libc::c_uint,
-    stdio_count: libc::c_int,
-    stdio: *uv_stdio_container_t,
-    uid: uv_uid_t,
-    gid: uv_gid_t,
-}
-
-// These fields are private because they must be interfaced with through the
-// functions below.
-pub struct uv_stdio_container_t {
-    priv flags: libc::c_int,
-    priv stream: *uv_stream_t,
-}
-
-pub type uv_handle_t = c_void;
-pub type uv_loop_t = c_void;
-pub type uv_idle_t = c_void;
-pub type uv_tcp_t = c_void;
-pub type uv_udp_t = c_void;
-pub type uv_connect_t = c_void;
-pub type uv_connection_t = c_void;
-pub type uv_write_t = c_void;
-pub type uv_async_t = c_void;
-pub type uv_timer_t = c_void;
-pub type uv_stream_t = c_void;
-pub type uv_fs_t = c_void;
-pub type uv_udp_send_t = c_void;
-pub type uv_getaddrinfo_t = c_void;
-pub type uv_process_t = c_void;
-pub type uv_pipe_t = c_void;
-pub type uv_tty_t = c_void;
-pub type uv_signal_t = c_void;
-
-pub struct uv_timespec_t {
-    tv_sec: libc::c_long,
-    priv tv_nsec: libc::c_long
-}
-
-pub struct uv_stat_t {
-    st_dev: libc::uint64_t,
-    st_mode: libc::uint64_t,
-    priv st_nlink: libc::uint64_t,
-    priv st_uid: libc::uint64_t,
-    priv st_gid: libc::uint64_t,
-    priv st_rdev: libc::uint64_t,
-    st_ino: libc::uint64_t,
-    st_size: libc::uint64_t,
-    priv st_blksize: libc::uint64_t,
-    priv st_blocks: libc::uint64_t,
-    priv st_flags: libc::uint64_t,
-    priv st_gen: libc::uint64_t,
-    st_atim: uv_timespec_t,
-    st_mtim: uv_timespec_t,
-    st_ctim: uv_timespec_t,
-    priv st_birthtim: uv_timespec_t
-}
-
-impl uv_stat_t {
-    pub fn new() -> uv_stat_t {
-        uv_stat_t {
-            st_dev: 0,
-            st_mode: 0,
-            st_nlink: 0,
-            st_uid: 0,
-            st_gid: 0,
-            st_rdev: 0,
-            st_ino: 0,
-            st_size: 0,
-            st_blksize: 0,
-            st_blocks: 0,
-            st_flags: 0,
-            st_gen: 0,
-            st_atim: uv_timespec_t { tv_sec: 0, tv_nsec: 0 },
-            st_mtim: uv_timespec_t { tv_sec: 0, tv_nsec: 0 },
-            st_ctim: uv_timespec_t { tv_sec: 0, tv_nsec: 0 },
-            st_birthtim: uv_timespec_t { tv_sec: 0, tv_nsec: 0 }
-        }
-    }
-    pub fn is_file(&self) -> bool {
-        ((self.st_mode) & libc::S_IFMT as libc::uint64_t) == libc::S_IFREG as libc::uint64_t
-    }
-    pub fn is_dir(&self) -> bool {
-        ((self.st_mode) & libc::S_IFMT as libc::uint64_t) == libc::S_IFDIR as libc::uint64_t
-    }
-}
-
-pub type uv_idle_cb = extern "C" fn(handle: *uv_idle_t,
-                                    status: c_int);
-pub type uv_alloc_cb = extern "C" fn(stream: *uv_stream_t,
-                                     suggested_size: size_t) -> uv_buf_t;
-pub type uv_read_cb = extern "C" fn(stream: *uv_stream_t,
-                                    nread: ssize_t,
-                                    buf: uv_buf_t);
-pub type uv_udp_send_cb = extern "C" fn(req: *uv_udp_send_t,
-                                        status: c_int);
-pub type uv_udp_recv_cb = extern "C" fn(handle: *uv_udp_t,
-                                        nread: ssize_t,
-                                        buf: uv_buf_t,
-                                        addr: *sockaddr,
-                                        flags: c_uint);
-pub type uv_close_cb = extern "C" fn(handle: *uv_handle_t);
-pub type uv_walk_cb = extern "C" fn(handle: *uv_handle_t,
-                                    arg: *c_void);
-pub type uv_async_cb = extern "C" fn(handle: *uv_async_t,
-                                     status: c_int);
-pub type uv_connect_cb = extern "C" fn(handle: *uv_connect_t,
-                                       status: c_int);
-pub type uv_connection_cb = extern "C" fn(handle: *uv_connection_t,
-                                          status: c_int);
-pub type uv_timer_cb = extern "C" fn(handle: *uv_timer_t,
-                                     status: c_int);
-pub type uv_write_cb = extern "C" fn(handle: *uv_write_t,
-                                     status: c_int);
-pub type uv_getaddrinfo_cb = extern "C" fn(req: *uv_getaddrinfo_t,
-                                           status: c_int,
-                                           res: *addrinfo);
-pub type uv_exit_cb = extern "C" fn(handle: *uv_process_t,
-                                    exit_status: c_int,
-                                    term_signal: c_int);
-pub type uv_signal_cb = extern "C" fn(handle: *uv_signal_t,
-                                      signum: c_int);
-
-pub type sockaddr = c_void;
-pub type sockaddr_in = c_void;
-pub type sockaddr_in6 = c_void;
-pub type sockaddr_storage = c_void;
-
-#[cfg(unix)]
-pub type socklen_t = c_int;
-
-// XXX: This is a standard C type. Could probably be defined in libc
-#[cfg(target_os = "android")]
-#[cfg(target_os = "linux")]
-pub struct addrinfo {
-    ai_flags: c_int,
-    ai_family: c_int,
-    ai_socktype: c_int,
-    ai_protocol: c_int,
-    ai_addrlen: socklen_t,
-    ai_addr: *sockaddr,
-    ai_canonname: *char,
-    ai_next: *addrinfo
-}
-
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "freebsd")]
-pub struct addrinfo {
-    ai_flags: c_int,
-    ai_family: c_int,
-    ai_socktype: c_int,
-    ai_protocol: c_int,
-    ai_addrlen: socklen_t,
-    ai_canonname: *char,
-    ai_addr: *sockaddr,
-    ai_next: *addrinfo
-}
-
-#[cfg(windows)]
-pub struct addrinfo {
-    ai_flags: c_int,
-    ai_family: c_int,
-    ai_socktype: c_int,
-    ai_protocol: c_int,
-    ai_addrlen: size_t,
-    ai_canonname: *char,
-    ai_addr: *sockaddr,
-    ai_next: *addrinfo
-}
-
-#[cfg(unix)] pub type uv_uid_t = libc::types::os::arch::posix88::uid_t;
-#[cfg(unix)] pub type uv_gid_t = libc::types::os::arch::posix88::gid_t;
-#[cfg(windows)] pub type uv_uid_t = libc::c_uchar;
-#[cfg(windows)] pub type uv_gid_t = libc::c_uchar;
-
-#[deriving(Eq)]
-pub enum uv_handle_type {
-    UV_UNKNOWN_HANDLE,
-    UV_ASYNC,
-    UV_CHECK,
-    UV_FS_EVENT,
-    UV_FS_POLL,
-    UV_HANDLE,
-    UV_IDLE,
-    UV_NAMED_PIPE,
-    UV_POLL,
-    UV_PREPARE,
-    UV_PROCESS,
-    UV_STREAM,
-    UV_TCP,
-    UV_TIMER,
-    UV_TTY,
-    UV_UDP,
-    UV_SIGNAL,
-    UV_FILE,
-    UV_HANDLE_TYPE_MAX
-}
-
-#[cfg(unix)]
-#[deriving(Eq)]
-pub enum uv_req_type {
-    UV_UNKNOWN_REQ,
-    UV_REQ,
-    UV_CONNECT,
-    UV_WRITE,
-    UV_SHUTDOWN,
-    UV_UDP_SEND,
-    UV_FS,
-    UV_WORK,
-    UV_GETADDRINFO,
-    UV_REQ_TYPE_MAX
-}
-
-// uv_req_type may have additional fields defined by UV_REQ_TYPE_PRIVATE.
-// See UV_REQ_TYPE_PRIVATE at libuv/include/uv-win.h
-#[cfg(windows)]
-#[deriving(Eq)]
-pub enum uv_req_type {
-    UV_UNKNOWN_REQ,
-    UV_REQ,
-    UV_CONNECT,
-    UV_WRITE,
-    UV_SHUTDOWN,
-    UV_UDP_SEND,
-    UV_FS,
-    UV_WORK,
-    UV_GETADDRINFO,
-    UV_ACCEPT,
-    UV_FS_EVENT_REQ,
-    UV_POLL_REQ,
-    UV_PROCESS_EXIT,
-    UV_READ,
-    UV_UDP_RECV,
-    UV_WAKEUP,
-    UV_SIGNAL_REQ,
-    UV_REQ_TYPE_MAX
-}
-
-#[deriving(Eq)]
-pub enum uv_membership {
-    UV_LEAVE_GROUP,
-    UV_JOIN_GROUP
-}
-
-pub unsafe fn malloc_handle(handle: uv_handle_type) -> *c_void {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    assert!(handle != UV_UNKNOWN_HANDLE && handle != UV_HANDLE_TYPE_MAX);
-    let size = rust_uv_handle_size(handle as uint);
-    let p = malloc(size);
-    assert!(p.is_not_null());
-    return p;
-}
-
-pub unsafe fn free_handle(v: *c_void) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    free(v)
-}
-
-pub unsafe fn malloc_req(req: uv_req_type) -> *c_void {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    assert!(req != UV_UNKNOWN_REQ && req != UV_REQ_TYPE_MAX);
-    let size = rust_uv_req_size(req as uint);
-    let p = malloc(size);
-    assert!(p.is_not_null());
-    return p;
-}
-
-pub unsafe fn free_req(v: *c_void) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    free(v)
-}
-
-#[test]
-fn handle_sanity_check() {
-    #[fixed_stack_segment]; #[inline(never)];
-    unsafe {
-        assert_eq!(UV_HANDLE_TYPE_MAX as uint, rust_uv_handle_type_max());
-    }
-}
-
-#[test]
-fn request_sanity_check() {
-    #[fixed_stack_segment]; #[inline(never)];
-    unsafe {
-        assert_eq!(UV_REQ_TYPE_MAX as uint, rust_uv_req_type_max());
-    }
-}
-
-// XXX Event loops ignore SIGPIPE by default.
-pub unsafe fn loop_new() -> *c_void {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_loop_new();
-}
-
-pub unsafe fn loop_delete(loop_handle: *c_void) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_loop_delete(loop_handle);
-}
-
-pub unsafe fn run(loop_handle: *c_void) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_run(loop_handle);
-}
-
-pub unsafe fn close<T>(handle: *T, cb: uv_close_cb) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_close(handle as *c_void, cb);
-}
-
-pub unsafe fn walk(loop_handle: *c_void, cb: uv_walk_cb, arg: *c_void) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_walk(loop_handle, cb, arg);
-}
-
-pub unsafe fn idle_init(loop_handle: *uv_loop_t, handle: *uv_idle_t) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_idle_init(loop_handle, handle)
-}
-
-pub unsafe fn idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_idle_start(handle, cb)
-}
-
-pub unsafe fn idle_stop(handle: *uv_idle_t) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_idle_stop(handle)
-}
-
-pub unsafe fn udp_init(loop_handle: *uv_loop_t, handle: *uv_udp_t) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_udp_init(loop_handle, handle);
-}
-
-pub unsafe fn udp_bind(server: *uv_udp_t, addr: *sockaddr_in, flags: c_uint) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_udp_bind(server, addr, flags);
-}
-
-pub unsafe fn udp_bind6(server: *uv_udp_t, addr: *sockaddr_in6, flags: c_uint) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_udp_bind6(server, addr, flags);
-}
-
-pub unsafe fn udp_send<T>(req: *uv_udp_send_t, handle: *T, buf_in: &[uv_buf_t],
-                          addr: *sockaddr_in, cb: uv_udp_send_cb) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    let buf_ptr = vec::raw::to_ptr(buf_in);
-    let buf_cnt = buf_in.len() as i32;
-    return rust_uv_udp_send(req, handle as *c_void, buf_ptr, buf_cnt, addr, cb);
-}
-
-pub unsafe fn udp_send6<T>(req: *uv_udp_send_t, handle: *T, buf_in: &[uv_buf_t],
-                          addr: *sockaddr_in6, cb: uv_udp_send_cb) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    let buf_ptr = vec::raw::to_ptr(buf_in);
-    let buf_cnt = buf_in.len() as i32;
-    return rust_uv_udp_send6(req, handle as *c_void, buf_ptr, buf_cnt, addr, cb);
-}
-
-pub unsafe fn udp_recv_start(server: *uv_udp_t, on_alloc: uv_alloc_cb,
-                             on_recv: uv_udp_recv_cb) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_udp_recv_start(server, on_alloc, on_recv);
-}
-
-pub unsafe fn udp_recv_stop(server: *uv_udp_t) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_udp_recv_stop(server);
-}
-
-pub unsafe fn get_udp_handle_from_send_req(send_req: *uv_udp_send_t) -> *uv_udp_t {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_get_udp_handle_from_send_req(send_req);
-}
-
-pub unsafe fn udp_getsockname(handle: *uv_udp_t, name: *sockaddr_storage) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_udp_getsockname(handle, name);
-}
-
-pub unsafe fn udp_set_membership(handle: *uv_udp_t, multicast_addr: *c_char,
-                                 interface_addr: *c_char, membership: uv_membership) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_udp_set_membership(handle, multicast_addr, interface_addr, membership as c_int);
-}
-
-pub unsafe fn udp_set_multicast_loop(handle: *uv_udp_t, on: c_int) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_udp_set_multicast_loop(handle, on);
-}
-
-pub unsafe fn udp_set_multicast_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_udp_set_multicast_ttl(handle, ttl);
-}
-
-pub unsafe fn udp_set_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_udp_set_ttl(handle, ttl);
-}
-
-pub unsafe fn udp_set_broadcast(handle: *uv_udp_t, on: c_int) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_udp_set_broadcast(handle, on);
-}
-
-pub unsafe fn tcp_init(loop_handle: *c_void, handle: *uv_tcp_t) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_tcp_init(loop_handle, handle);
-}
-
-pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t,
-                          addr_ptr: *sockaddr_in, after_connect_cb: uv_connect_cb) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr, after_connect_cb, addr_ptr);
-}
-
-pub unsafe fn tcp_connect6(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t,
-                           addr_ptr: *sockaddr_in6, after_connect_cb: uv_connect_cb) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_tcp_connect6(connect_ptr, tcp_handle_ptr, after_connect_cb, addr_ptr);
-}
-
-pub unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_tcp_bind(tcp_server_ptr, addr_ptr);
-}
-
-pub unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in6) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_tcp_bind6(tcp_server_ptr, addr_ptr);
-}
-
-pub unsafe fn tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_storage) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_tcp_getpeername(tcp_handle_ptr, name);
-}
-
-pub unsafe fn tcp_getsockname(handle: *uv_tcp_t, name: *sockaddr_storage) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_tcp_getsockname(handle, name);
-}
-
-pub unsafe fn tcp_nodelay(handle: *uv_tcp_t, enable: c_int) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_tcp_nodelay(handle, enable);
-}
-
-pub unsafe fn tcp_keepalive(handle: *uv_tcp_t, enable: c_int, delay: c_uint) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_tcp_keepalive(handle, enable, delay);
-}
-
-pub unsafe fn tcp_simultaneous_accepts(handle: *uv_tcp_t, enable: c_int) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_tcp_simultaneous_accepts(handle, enable);
-}
-
-pub unsafe fn listen<T>(stream: *T, backlog: c_int,
-                        cb: uv_connection_cb) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_listen(stream as *c_void, backlog, cb);
-}
-
-pub unsafe fn accept(server: *c_void, client: *c_void) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_accept(server as *c_void, client as *c_void);
-}
-
-pub unsafe fn write<T>(req: *uv_write_t,
-                       stream: *T,
-                       buf_in: &[uv_buf_t],
-                       cb: uv_write_cb) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    let buf_ptr = vec::raw::to_ptr(buf_in);
-    let buf_cnt = buf_in.len() as i32;
-    return rust_uv_write(req as *c_void, stream as *c_void, buf_ptr, buf_cnt, cb);
-}
-pub unsafe fn read_start(stream: *uv_stream_t,
-                         on_alloc: uv_alloc_cb,
-                         on_read: uv_read_cb) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_read_start(stream as *c_void, on_alloc, on_read);
-}
-
-pub unsafe fn read_stop(stream: *uv_stream_t) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_read_stop(stream as *c_void);
-}
-
-pub unsafe fn strerror(err: c_int) -> *c_char {
-    #[fixed_stack_segment]; #[inline(never)];
-    return rust_uv_strerror(err);
-}
-pub unsafe fn err_name(err: c_int) -> *c_char {
-    #[fixed_stack_segment]; #[inline(never)];
-    return rust_uv_err_name(err);
-}
-
-pub unsafe fn async_init(loop_handle: *c_void,
-                         async_handle: *uv_async_t,
-                         cb: uv_async_cb) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_async_init(loop_handle, async_handle, cb);
-}
-
-pub unsafe fn async_send(async_handle: *uv_async_t) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_async_send(async_handle);
-}
-pub unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    let out_buf = uv_buf_t { base: ptr::null(), len: 0 as size_t };
-    let out_buf_ptr = ptr::to_unsafe_ptr(&out_buf);
-    rust_uv_buf_init(out_buf_ptr, input, len as size_t);
-    return out_buf;
-}
-
-pub unsafe fn timer_init(loop_ptr: *c_void, timer_ptr: *uv_timer_t) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_timer_init(loop_ptr, timer_ptr);
-}
-pub unsafe fn timer_start(timer_ptr: *uv_timer_t,
-                          cb: uv_timer_cb, timeout: u64,
-                          repeat: u64) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_timer_start(timer_ptr, cb, timeout, repeat);
-}
-pub unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_timer_stop(timer_ptr);
-}
-
-pub unsafe fn is_ip4_addr(addr: *sockaddr) -> bool {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    match rust_uv_is_ipv4_sockaddr(addr) { 0 => false, _ => true }
-}
-
-pub unsafe fn is_ip6_addr(addr: *sockaddr) -> bool {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    match rust_uv_is_ipv6_sockaddr(addr) { 0 => false, _ => true }
-}
-
-pub unsafe fn malloc_ip4_addr(ip: &str, port: int) -> *sockaddr_in {
-    #[fixed_stack_segment]; #[inline(never)];
-    do ip.with_c_str |ip_buf| {
-        rust_uv_ip4_addrp(ip_buf as *u8, port as libc::c_int)
-    }
-}
-pub unsafe fn malloc_ip6_addr(ip: &str, port: int) -> *sockaddr_in6 {
-    #[fixed_stack_segment]; #[inline(never)];
-    do ip.with_c_str |ip_buf| {
-        rust_uv_ip6_addrp(ip_buf as *u8, port as libc::c_int)
-    }
-}
-
-pub unsafe fn malloc_sockaddr_storage() -> *sockaddr_storage {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_malloc_sockaddr_storage()
-}
-
-pub unsafe fn free_sockaddr_storage(ss: *sockaddr_storage) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_free_sockaddr_storage(ss);
-}
-
-pub unsafe fn free_ip4_addr(addr: *sockaddr_in) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_free_ip4_addr(addr);
-}
-
-pub unsafe fn free_ip6_addr(addr: *sockaddr_in6) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_free_ip6_addr(addr);
-}
-
-pub unsafe fn ip4_name(addr: *sockaddr_in, dst: *u8, size: size_t) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_ip4_name(addr, dst, size);
-}
-
-pub unsafe fn ip6_name(addr: *sockaddr_in6, dst: *u8, size: size_t) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_ip6_name(addr, dst, size);
-}
-
-pub unsafe fn ip4_port(addr: *sockaddr_in) -> c_uint {
-    #[fixed_stack_segment]; #[inline(never)];
-
-   return rust_uv_ip4_port(addr);
-}
-
-pub unsafe fn ip6_port(addr: *sockaddr_in6) -> c_uint {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_ip6_port(addr);
-}
-
-pub unsafe fn fs_open(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char, flags: int, mode: int,
-                cb: *u8) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_fs_open(loop_ptr, req, path, flags as c_int, mode as c_int, cb)
-}
-
-pub unsafe fn fs_unlink(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char,
-                cb: *u8) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_fs_unlink(loop_ptr, req, path, cb)
-}
-pub unsafe fn fs_write(loop_ptr: *uv_loop_t, req: *uv_fs_t, fd: c_int, buf: *c_void,
-                       len: uint, offset: i64, cb: *u8) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_fs_write(loop_ptr, req, fd, buf, len as c_uint, offset, cb)
-}
-pub unsafe fn fs_read(loop_ptr: *uv_loop_t, req: *uv_fs_t, fd: c_int, buf: *c_void,
-                       len: uint, offset: i64, cb: *u8) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_fs_read(loop_ptr, req, fd, buf, len as c_uint, offset, cb)
-}
-pub unsafe fn fs_close(loop_ptr: *uv_loop_t, req: *uv_fs_t, fd: c_int,
-                cb: *u8) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_fs_close(loop_ptr, req, fd, cb)
-}
-pub unsafe fn fs_stat(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char, cb: *u8) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_fs_stat(loop_ptr, req, path, cb)
-}
-pub unsafe fn fs_fstat(loop_ptr: *uv_loop_t, req: *uv_fs_t, fd: c_int, cb: *u8) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_fs_fstat(loop_ptr, req, fd, cb)
-}
-pub unsafe fn fs_mkdir(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char, mode: int,
-                cb: *u8) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_fs_mkdir(loop_ptr, req, path, mode as c_int, cb)
-}
-pub unsafe fn fs_rmdir(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char,
-                cb: *u8) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_fs_rmdir(loop_ptr, req, path, cb)
-}
-pub unsafe fn fs_readdir(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char,
-                flags: c_int, cb: *u8) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_fs_readdir(loop_ptr, req, path, flags, cb)
-}
-pub unsafe fn populate_stat(req_in: *uv_fs_t, stat_out: *uv_stat_t) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_populate_uv_stat(req_in, stat_out)
-}
-pub unsafe fn fs_req_cleanup(req: *uv_fs_t) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_fs_req_cleanup(req);
-}
-
-pub unsafe fn spawn(loop_ptr: *c_void, result: *uv_process_t,
-                    options: uv_process_options_t) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-    return rust_uv_spawn(loop_ptr, result, options);
-}
-
-pub unsafe fn process_kill(p: *uv_process_t, signum: c_int) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-    return rust_uv_process_kill(p, signum);
-}
-
-pub unsafe fn process_pid(p: *uv_process_t) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-    return rust_uv_process_pid(p);
-}
-
-pub unsafe fn set_stdio_container_flags(c: *uv_stdio_container_t,
-                                        flags: libc::c_int) {
-    #[fixed_stack_segment]; #[inline(never)];
-    rust_set_stdio_container_flags(c, flags);
-}
-
-pub unsafe fn set_stdio_container_fd(c: *uv_stdio_container_t,
-                                     fd: libc::c_int) {
-    #[fixed_stack_segment]; #[inline(never)];
-    rust_set_stdio_container_fd(c, fd);
-}
-
-pub unsafe fn set_stdio_container_stream(c: *uv_stdio_container_t,
-                                         stream: *uv_stream_t) {
-    #[fixed_stack_segment]; #[inline(never)];
-    rust_set_stdio_container_stream(c, stream);
-}
-
-pub unsafe fn pipe_init(loop_ptr: *c_void, p: *uv_pipe_t, ipc: c_int) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-    rust_uv_pipe_init(loop_ptr, p, ipc)
-}
-
-// data access helpers
-pub unsafe fn get_result_from_fs_req(req: *uv_fs_t) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_get_result_from_fs_req(req)
-}
-pub unsafe fn get_ptr_from_fs_req(req: *uv_fs_t) -> *libc::c_void {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_get_ptr_from_fs_req(req)
-}
-pub unsafe fn get_loop_from_fs_req(req: *uv_fs_t) -> *uv_loop_t {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_get_loop_from_fs_req(req)
-}
-pub unsafe fn get_loop_from_getaddrinfo_req(req: *uv_getaddrinfo_t) -> *uv_loop_t {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_get_loop_from_getaddrinfo_req(req)
-}
-pub unsafe fn get_loop_for_uv_handle<T>(handle: *T) -> *c_void {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_get_loop_for_uv_handle(handle as *c_void);
-}
-pub unsafe fn get_stream_handle_from_connect_req(connect: *uv_connect_t) -> *uv_stream_t {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_get_stream_handle_from_connect_req(connect);
-}
-pub unsafe fn get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_get_stream_handle_from_write_req(write_req);
-}
-pub unsafe fn get_data_for_uv_loop(loop_ptr: *c_void) -> *c_void {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_get_data_for_uv_loop(loop_ptr)
-}
-pub unsafe fn set_data_for_uv_loop(loop_ptr: *c_void, data: *c_void) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_set_data_for_uv_loop(loop_ptr, data);
-}
-pub unsafe fn get_data_for_uv_handle<T>(handle: *T) -> *c_void {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_get_data_for_uv_handle(handle as *c_void);
-}
-pub unsafe fn set_data_for_uv_handle<T, U>(handle: *T, data: *U) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_set_data_for_uv_handle(handle as *c_void, data as *c_void);
-}
-pub unsafe fn get_data_for_req<T>(req: *T) -> *c_void {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_get_data_for_req(req as *c_void);
-}
-pub unsafe fn set_data_for_req<T, U>(req: *T, data: *U) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_set_data_for_req(req as *c_void, data as *c_void);
-}
-pub unsafe fn get_base_from_buf(buf: uv_buf_t) -> *u8 {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_get_base_from_buf(buf);
-}
-pub unsafe fn get_len_from_buf(buf: uv_buf_t) -> size_t {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_get_len_from_buf(buf);
-}
-pub unsafe fn getaddrinfo(loop_: *uv_loop_t, req: *uv_getaddrinfo_t,
-               getaddrinfo_cb: uv_getaddrinfo_cb,
-               node: *c_char, service: *c_char,
-               hints: *addrinfo) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-    return rust_uv_getaddrinfo(loop_, req, getaddrinfo_cb, node, service, hints);
-}
-pub unsafe fn freeaddrinfo(ai: *addrinfo) {
-    #[fixed_stack_segment]; #[inline(never)];
-    rust_uv_freeaddrinfo(ai);
-}
-pub unsafe fn pipe_open(pipe: *uv_pipe_t, file: c_int) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-    rust_uv_pipe_open(pipe, file)
-}
-pub unsafe fn pipe_bind(pipe: *uv_pipe_t, name: *c_char) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-    rust_uv_pipe_bind(pipe, name)
-}
-pub unsafe fn pipe_connect(req: *uv_connect_t, handle: *uv_pipe_t,
-                           name: *c_char, cb: uv_connect_cb) {
-    #[fixed_stack_segment]; #[inline(never)];
-    rust_uv_pipe_connect(req, handle, name, cb)
-}
-pub unsafe fn tty_init(loop_ptr: *uv_loop_t, tty: *uv_tty_t, fd: c_int,
-                       readable: c_int) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-    rust_uv_tty_init(loop_ptr, tty, fd, readable)
-}
-pub unsafe fn tty_set_mode(tty: *uv_tty_t, mode: c_int) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-    rust_uv_tty_set_mode(tty, mode)
-}
-pub unsafe fn tty_get_winsize(tty: *uv_tty_t, width: *c_int,
-                              height: *c_int) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-    rust_uv_tty_get_winsize(tty, width, height)
-}
-// FIXME(#9613) this should return uv_handle_type, not a c_int
-pub unsafe fn guess_handle(fd: c_int) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-    rust_uv_guess_handle(fd)
-}
-
-pub unsafe fn signal_init(loop_: *uv_loop_t, handle: *uv_signal_t) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-    return rust_uv_signal_init(loop_, handle);
-}
-pub unsafe fn signal_start(handle: *uv_signal_t,
-                           signal_cb: uv_signal_cb,
-                           signum: c_int) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-    return rust_uv_signal_start(handle, signal_cb, signum);
-}
-pub unsafe fn signal_stop(handle: *uv_signal_t) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-    return rust_uv_signal_stop(handle);
-}
-
-pub struct uv_err_data {
-    priv err_name: ~str,
-    priv err_msg: ~str,
-}
-
-extern {
-
-    fn rust_uv_handle_size(type_: uintptr_t) -> size_t;
-    fn rust_uv_req_size(type_: uintptr_t) -> size_t;
-    fn rust_uv_handle_type_max() -> uintptr_t;
-    fn rust_uv_req_type_max() -> uintptr_t;
-
-    // libuv public API
-    fn rust_uv_loop_new() -> *c_void;
-    fn rust_uv_loop_delete(lp: *c_void);
-    fn rust_uv_run(loop_handle: *c_void);
-    fn rust_uv_close(handle: *c_void, cb: uv_close_cb);
-    fn rust_uv_walk(loop_handle: *c_void, cb: uv_walk_cb, arg: *c_void);
-
-    fn rust_uv_idle_init(loop_handle: *uv_loop_t, handle: *uv_idle_t) -> c_int;
-    fn rust_uv_idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> c_int;
-    fn rust_uv_idle_stop(handle: *uv_idle_t) -> c_int;
-
-    fn rust_uv_async_send(handle: *uv_async_t);
-    fn rust_uv_async_init(loop_handle: *c_void,
-                          async_handle: *uv_async_t,
-                          cb: uv_async_cb) -> c_int;
-    fn rust_uv_tcp_init(loop_handle: *c_void, handle_ptr: *uv_tcp_t) -> c_int;
-    fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8, len: size_t);
-    fn rust_uv_strerror(err: c_int) -> *c_char;
-    fn rust_uv_err_name(err: c_int) -> *c_char;
-    fn rust_uv_ip4_addrp(ip: *u8, port: c_int) -> *sockaddr_in;
-    fn rust_uv_ip6_addrp(ip: *u8, port: c_int) -> *sockaddr_in6;
-    fn rust_uv_free_ip4_addr(addr: *sockaddr_in);
-    fn rust_uv_free_ip6_addr(addr: *sockaddr_in6);
-    fn rust_uv_ip4_name(src: *sockaddr_in, dst: *u8, size: size_t) -> c_int;
-    fn rust_uv_ip6_name(src: *sockaddr_in6, dst: *u8, size: size_t) -> c_int;
-    fn rust_uv_ip4_port(src: *sockaddr_in) -> c_uint;
-    fn rust_uv_ip6_port(src: *sockaddr_in6) -> c_uint;
-    fn rust_uv_tcp_connect(req: *uv_connect_t, handle: *uv_tcp_t,
-                           cb: uv_connect_cb,
-                           addr: *sockaddr_in) -> c_int;
-    fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, addr: *sockaddr_in) -> c_int;
-    fn rust_uv_tcp_connect6(req: *uv_connect_t, handle: *uv_tcp_t,
-                            cb: uv_connect_cb,
-                            addr: *sockaddr_in6) -> c_int;
-    fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, addr: *sockaddr_in6) -> c_int;
-    fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_storage) -> c_int;
-    fn rust_uv_tcp_getsockname(handle: *uv_tcp_t, name: *sockaddr_storage) -> c_int;
-    fn rust_uv_tcp_nodelay(handle: *uv_tcp_t, enable: c_int) -> c_int;
-    fn rust_uv_tcp_keepalive(handle: *uv_tcp_t, enable: c_int, delay: c_uint) -> c_int;
-    fn rust_uv_tcp_simultaneous_accepts(handle: *uv_tcp_t, enable: c_int) -> c_int;
-
-    fn rust_uv_udp_init(loop_handle: *uv_loop_t, handle_ptr: *uv_udp_t) -> c_int;
-    fn rust_uv_udp_bind(server: *uv_udp_t, addr: *sockaddr_in, flags: c_uint) -> c_int;
-    fn rust_uv_udp_bind6(server: *uv_udp_t, addr: *sockaddr_in6, flags: c_uint) -> c_int;
-    fn rust_uv_udp_send(req: *uv_udp_send_t, handle: *uv_udp_t, buf_in: *uv_buf_t,
-                        buf_cnt: c_int, addr: *sockaddr_in, cb: uv_udp_send_cb) -> c_int;
-    fn rust_uv_udp_send6(req: *uv_udp_send_t, handle: *uv_udp_t, buf_in: *uv_buf_t,
-                         buf_cnt: c_int, addr: *sockaddr_in6, cb: uv_udp_send_cb) -> c_int;
-    fn rust_uv_udp_recv_start(server: *uv_udp_t,
-                              on_alloc: uv_alloc_cb,
-                              on_recv: uv_udp_recv_cb) -> c_int;
-    fn rust_uv_udp_recv_stop(server: *uv_udp_t) -> c_int;
-    fn rust_uv_get_udp_handle_from_send_req(req: *uv_udp_send_t) -> *uv_udp_t;
-    fn rust_uv_udp_getsockname(handle: *uv_udp_t, name: *sockaddr_storage) -> c_int;
-    fn rust_uv_udp_set_membership(handle: *uv_udp_t, multicast_addr: *c_char,
-                                  interface_addr: *c_char, membership: c_int) -> c_int;
-    fn rust_uv_udp_set_multicast_loop(handle: *uv_udp_t, on: c_int) -> c_int;
-    fn rust_uv_udp_set_multicast_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int;
-    fn rust_uv_udp_set_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int;
-    fn rust_uv_udp_set_broadcast(handle: *uv_udp_t, on: c_int) -> c_int;
-
-    fn rust_uv_is_ipv4_sockaddr(addr: *sockaddr) -> c_int;
-    fn rust_uv_is_ipv6_sockaddr(addr: *sockaddr) -> c_int;
-    fn rust_uv_malloc_sockaddr_storage() -> *sockaddr_storage;
-    fn rust_uv_free_sockaddr_storage(ss: *sockaddr_storage);
-
-    fn rust_uv_listen(stream: *c_void, backlog: c_int,
-                      cb: uv_connection_cb) -> c_int;
-    fn rust_uv_accept(server: *c_void, client: *c_void) -> c_int;
-    fn rust_uv_write(req: *c_void, stream: *c_void, buf_in: *uv_buf_t, buf_cnt: c_int,
-                     cb: uv_write_cb) -> c_int;
-    fn rust_uv_read_start(stream: *c_void,
-                          on_alloc: uv_alloc_cb,
-                          on_read: uv_read_cb) -> c_int;
-    fn rust_uv_read_stop(stream: *c_void) -> c_int;
-    fn rust_uv_timer_init(loop_handle: *c_void, timer_handle: *uv_timer_t) -> c_int;
-    fn rust_uv_timer_start(timer_handle: *uv_timer_t, cb: uv_timer_cb, timeout: libc::uint64_t,
-                           repeat: libc::uint64_t) -> c_int;
-    fn rust_uv_timer_stop(handle: *uv_timer_t) -> c_int;
-    fn rust_uv_fs_open(loop_ptr: *c_void, req: *uv_fs_t, path: *c_char,
-                       flags: c_int, mode: c_int, cb: *u8) -> c_int;
-    fn rust_uv_fs_unlink(loop_ptr: *c_void, req: *uv_fs_t, path: *c_char,
-                       cb: *u8) -> c_int;
-    fn rust_uv_fs_write(loop_ptr: *c_void, req: *uv_fs_t, fd: c_int,
-                       buf: *c_void, len: c_uint, offset: i64, cb: *u8) -> c_int;
-    fn rust_uv_fs_read(loop_ptr: *c_void, req: *uv_fs_t, fd: c_int,
-                       buf: *c_void, len: c_uint, offset: i64, cb: *u8) -> c_int;
-    fn rust_uv_fs_close(loop_ptr: *c_void, req: *uv_fs_t, fd: c_int,
-                        cb: *u8) -> c_int;
-    fn rust_uv_fs_stat(loop_ptr: *c_void, req: *uv_fs_t, path: *c_char, cb: *u8) -> c_int;
-    fn rust_uv_fs_fstat(loop_ptr: *c_void, req: *uv_fs_t, fd: c_int, cb: *u8) -> c_int;
-    fn rust_uv_fs_mkdir(loop_ptr: *c_void, req: *uv_fs_t, path: *c_char,
-                        mode: c_int, cb: *u8) -> c_int;
-    fn rust_uv_fs_rmdir(loop_ptr: *c_void, req: *uv_fs_t, path: *c_char,
-                        cb: *u8) -> c_int;
-    fn rust_uv_fs_readdir(loop_ptr: *c_void, req: *uv_fs_t, path: *c_char,
-                        flags: c_int, cb: *u8) -> c_int;
-    fn rust_uv_fs_req_cleanup(req: *uv_fs_t);
-    fn rust_uv_populate_uv_stat(req_in: *uv_fs_t, stat_out: *uv_stat_t);
-    fn rust_uv_get_result_from_fs_req(req: *uv_fs_t) -> c_int;
-    fn rust_uv_get_ptr_from_fs_req(req: *uv_fs_t) -> *libc::c_void;
-    fn rust_uv_get_loop_from_fs_req(req: *uv_fs_t) -> *uv_loop_t;
-    fn rust_uv_get_loop_from_getaddrinfo_req(req: *uv_fs_t) -> *uv_loop_t;
-
-    fn rust_uv_get_stream_handle_from_connect_req(connect_req: *uv_connect_t) -> *uv_stream_t;
-    fn rust_uv_get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t;
-    fn rust_uv_get_loop_for_uv_handle(handle: *c_void) -> *c_void;
-    fn rust_uv_get_data_for_uv_loop(loop_ptr: *c_void) -> *c_void;
-    fn rust_uv_set_data_for_uv_loop(loop_ptr: *c_void, data: *c_void);
-    fn rust_uv_get_data_for_uv_handle(handle: *c_void) -> *c_void;
-    fn rust_uv_set_data_for_uv_handle(handle: *c_void, data: *c_void);
-    fn rust_uv_get_data_for_req(req: *c_void) -> *c_void;
-    fn rust_uv_set_data_for_req(req: *c_void, data: *c_void);
-    fn rust_uv_get_base_from_buf(buf: uv_buf_t) -> *u8;
-    fn rust_uv_get_len_from_buf(buf: uv_buf_t) -> size_t;
-    fn rust_uv_getaddrinfo(loop_: *uv_loop_t, req: *uv_getaddrinfo_t,
-                           getaddrinfo_cb: uv_getaddrinfo_cb,
-                           node: *c_char, service: *c_char,
-                           hints: *addrinfo) -> c_int;
-    fn rust_uv_freeaddrinfo(ai: *addrinfo);
-    fn rust_uv_spawn(loop_ptr: *c_void, outptr: *uv_process_t,
-                     options: uv_process_options_t) -> c_int;
-    fn rust_uv_process_kill(p: *uv_process_t, signum: c_int) -> c_int;
-    fn rust_uv_process_pid(p: *uv_process_t) -> c_int;
-    fn rust_set_stdio_container_flags(c: *uv_stdio_container_t, flags: c_int);
-    fn rust_set_stdio_container_fd(c: *uv_stdio_container_t, fd: c_int);
-    fn rust_set_stdio_container_stream(c: *uv_stdio_container_t,
-                                       stream: *uv_stream_t);
-    fn rust_uv_pipe_init(loop_ptr: *c_void, p: *uv_pipe_t, ipc: c_int) -> c_int;
-
-    fn rust_uv_pipe_open(pipe: *uv_pipe_t, file: c_int) -> c_int;
-    fn rust_uv_pipe_bind(pipe: *uv_pipe_t, name: *c_char) -> c_int;
-    fn rust_uv_pipe_connect(req: *uv_connect_t, handle: *uv_pipe_t,
-                            name: *c_char, cb: uv_connect_cb);
-    fn rust_uv_tty_init(loop_ptr: *uv_loop_t, tty: *uv_tty_t, fd: c_int,
-                        readable: c_int) -> c_int;
-    fn rust_uv_tty_set_mode(tty: *uv_tty_t, mode: c_int) -> c_int;
-    fn rust_uv_tty_get_winsize(tty: *uv_tty_t, width: *c_int,
-                               height: *c_int) -> c_int;
-    fn rust_uv_guess_handle(fd: c_int) -> c_int;
-
-    // XXX: see comments in addrinfo.rs
-    // These should all really be constants...
-    //#[rust_stack] pub fn rust_SOCK_STREAM() -> c_int;
-    //#[rust_stack] pub fn rust_SOCK_DGRAM() -> c_int;
-    //#[rust_stack] pub fn rust_SOCK_RAW() -> c_int;
-    //#[rust_stack] pub fn rust_IPPROTO_UDP() -> c_int;
-    //#[rust_stack] pub fn rust_IPPROTO_TCP() -> c_int;
-    //#[rust_stack] pub fn rust_AI_ADDRCONFIG() -> c_int;
-    //#[rust_stack] pub fn rust_AI_ALL() -> c_int;
-    //#[rust_stack] pub fn rust_AI_CANONNAME() -> c_int;
-    //#[rust_stack] pub fn rust_AI_NUMERICHOST() -> c_int;
-    //#[rust_stack] pub fn rust_AI_NUMERICSERV() -> c_int;
-    //#[rust_stack] pub fn rust_AI_PASSIVE() -> c_int;
-    //#[rust_stack] pub fn rust_AI_V4MAPPED() -> c_int;
-
-    fn rust_uv_signal_init(loop_: *uv_loop_t, handle: *uv_signal_t) -> c_int;
-    fn rust_uv_signal_start(handle: *uv_signal_t,
-                            signal_cb: uv_signal_cb,
-                            signum: c_int) -> c_int;
-    fn rust_uv_signal_stop(handle: *uv_signal_t) -> c_int;
-}
index 3a96cfb11718d24a6b961ffc28d560a6f274d314..df6c47a8492bea86078dc28589b1bb49692d4dfe 100644 (file)
@@ -184,6 +184,8 @@ pub mod linkhack {
 pub mod path;
 pub mod rand;
 pub mod run;
+// NOTE: Remove module after next snapshot
+#[cfg(stage0)]
 pub mod sys;
 pub mod cast;
 pub mod fmt;
@@ -226,7 +228,10 @@ mod std {
     pub use logging;
     pub use option;
     pub use os;
+    pub use rt;
     pub use str;
+    // NOTE: Remove import after next snapshot
+    #[cfg(stage0)]
     pub use sys;
     pub use to_bytes;
     pub use to_str;
index b35b25aeb6f727e22bc6c31bb49489f729cdf132..4216f91b60263993873861ef974220e2c61bcd1c 100644 (file)
 
 //! Misc low level stuff
 
+// NOTE: Remove this module after an snapshot
+
 #[allow(missing_doc)];
 
 use any::Any;
 use kinds::Send;
-use rt::task::{UnwindReasonStr, UnwindReasonAny};
 use rt::task;
-use send_str::{SendStr, IntoSendStr};
 
-/// Trait for initiating task failure with a sendable cause.
 pub trait FailWithCause {
-    /// Fail the current task with `cause`.
     fn fail_with(cause: Self, file: &'static str, line: uint) -> !;
 }
 
-impl FailWithCause for ~str {
-    fn fail_with(cause: ~str, file: &'static str, line: uint) -> ! {
-        task::begin_unwind_reason(UnwindReasonStr(cause.into_send_str()), file, line)
-    }
-}
-
-impl FailWithCause for &'static str {
-    fn fail_with(cause: &'static str, file: &'static str, line: uint) -> ! {
-        task::begin_unwind_reason(UnwindReasonStr(cause.into_send_str()), file, line)
-    }
-}
-
-impl FailWithCause for SendStr {
-    fn fail_with(cause: SendStr, file: &'static str, line: uint) -> ! {
-        task::begin_unwind_reason(UnwindReasonStr(cause), file, line)
-    }
-}
-
-impl FailWithCause for ~Any {
-    fn fail_with(cause: ~Any, file: &'static str, line: uint) -> ! {
-        task::begin_unwind_reason(UnwindReasonAny(cause), file, line)
-    }
-}
-
-impl<T: Any + Send + 'static> FailWithCause for ~T {
-    fn fail_with(cause: ~T, file: &'static str, line: uint) -> ! {
-        task::begin_unwind_reason(UnwindReasonAny(cause as ~Any), file, line)
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    use any::Any;
-    use cast;
-    use send_str::IntoSendStr;
-
-    #[test]
-    fn synthesize_closure() {
-        use unstable::raw::Closure;
-        unsafe {
-            let x = 10;
-            let f: &fn(int) -> int = |y| x + y;
-
-            assert_eq!(f(20), 30);
-
-            let original_closure: Closure = cast::transmute(f);
-
-            let actual_function_pointer = original_closure.code;
-            let environment = original_closure.env;
-
-            let new_closure = Closure {
-                code: actual_function_pointer,
-                env: environment
-            };
-
-            let new_f: &fn(int) -> int = cast::transmute(new_closure);
-            assert_eq!(new_f(20), 30);
-        }
+impl<T: Any + Send> FailWithCause for T {
+    fn fail_with(msg: T, file: &'static str, line: uint) -> ! {
+        task::begin_unwind(msg, file, line)
     }
-
-    #[test]
-    #[should_fail]
-    fn fail_static() { FailWithCause::fail_with("cause", file!(), line!()) }
-
-    #[test]
-    #[should_fail]
-    fn fail_owned() { FailWithCause::fail_with(~"cause", file!(), line!()) }
-
-    #[test]
-    #[should_fail]
-    fn fail_send() { FailWithCause::fail_with("cause".into_send_str(), file!(), line!()) }
-
-    #[test]
-    #[should_fail]
-    fn fail_any() { FailWithCause::fail_with(~612_u16 as ~Any, file!(), line!()) }
-
-    #[test]
-    #[should_fail]
-    fn fail_any_wrap() { FailWithCause::fail_with(~413_u16, file!(), line!()) }
 }
index 023ba6f7108a23a16ffd8f90e7eb2bc72e45fc5f..cdb70f00dfe57f3c22f33974d8cc5a6085303420 100644 (file)
@@ -60,7 +60,8 @@
 use result::{Result, Ok, Err};
 use rt::in_green_task_context;
 use rt::local::Local;
-use rt::task::{UnwindReasonAny, UnwindReasonLinked, UnwindReasonStr};
+use rt::task::{UnwindMessageAny, UnwindMessageLinked};
+use rt::task::{UnwindMessageStrStatic, UnwindMessageStrOwned};
 use rt::task::{UnwindResult, Success, Failure};
 use send_str::{SendStr, IntoSendStr};
 use unstable::finally::Finally;
 fn wrap_as_any(res: UnwindResult) -> TaskResult {
     match res {
         Success => Ok(()),
-        Failure(UnwindReasonStr(s)) => Err(~s as ~Any),
-        Failure(UnwindReasonAny(a)) => Err(a),
-        Failure(UnwindReasonLinked) => Err(~LinkedFailure as ~Any)
+        Failure(UnwindMessageAny(a)) => Err(a),
+        Failure(UnwindMessageLinked) => Err(~LinkedFailure as ~Any),
+        Failure(UnwindMessageStrOwned(s))  => Err(~s as ~Any),
+        Failure(UnwindMessageStrStatic(s)) => Err(~s as ~Any),
     }
 }
 
@@ -1425,38 +1427,52 @@ fn test_indestructible() {
 }
 
 #[test]
-fn test_try_fail_cause_static_str() {
+fn test_try_fail_message_static_str() {
     match do try {
         fail!("static string");
     } {
-        Err(ref e) if e.is::<SendStr>() => {}
-        Err(_) | Ok(()) => fail!()
+        Err(e) => {
+            type T = &'static str;
+            assert!(e.is::<T>());
+            assert_eq!(*e.move::<T>().unwrap(), "static string");
+        }
+        Ok(()) => fail!()
     }
 }
 
 #[test]
-fn test_try_fail_cause_owned_str() {
+fn test_try_fail_message_owned_str() {
     match do try {
         fail!(~"owned string");
     } {
-        Err(ref e) if e.is::<SendStr>() => {}
-        Err(_) | Ok(()) => fail!()
+        Err(e) => {
+            type T = ~str;
+            assert!(e.is::<T>());
+            assert_eq!(*e.move::<T>().unwrap(), ~"owned string");
+        }
+        Ok(()) => fail!()
     }
 }
 
 #[test]
-fn test_try_fail_cause_any() {
+fn test_try_fail_message_any() {
     match do try {
         fail!(~413u16 as ~Any);
     } {
-        Err(ref e) if e.is::<u16>() => {}
-        Err(_) | Ok(()) => fail!()
+        Err(e) => {
+            type T = ~Any;
+            assert!(e.is::<T>());
+            let any = e.move::<T>().unwrap();
+            assert!(any.is::<u16>());
+            assert_eq!(*any.move::<u16>().unwrap(), 413u16);
+        }
+        Ok(()) => fail!()
     }
 }
 
 #[ignore(reason = "linked failure")]
 #[test]
-fn test_try_fail_cause_linked() {
+fn test_try_fail_message_linked() {
     match do try {
         do spawn {
             fail!()
@@ -1468,11 +1484,11 @@ fn test_try_fail_cause_linked() {
 }
 
 #[test]
-fn test_try_fail_cause_any_wrapped() {
+fn test_try_fail_message_unit_struct() {
     struct Juju;
 
     match do try {
-        fail!(~Juju)
+        fail!(Juju)
     } {
         Err(ref e) if e.is::<Juju>() => {}
         Err(_) | Ok(()) => fail!()
index a08bf8f3147b86e81970791d3d32d9e5f7566059..4a98e396bbccd7bd316be338d51c2bc1fd25f846 100644 (file)
 use rt::local::Local;
 use rt::sched::{Scheduler, Shutdown, TaskFromFriend};
 use rt::task::{Task, Sched};
-use rt::task::{UnwindReasonLinked, UnwindReasonStr};
+use rt::task::{UnwindMessageLinked, UnwindMessageStrStatic};
 use rt::task::{UnwindResult, Success, Failure};
 use rt::thread::Thread;
 use rt::work_queue::WorkQueue;
 use rt::{in_green_task_context, new_event_loop, KillHandle};
-use send_str::IntoSendStr;
 use task::SingleThreaded;
 use task::TaskOpts;
 use task::unkillable;
@@ -325,7 +324,7 @@ fn drop(&mut self) {
         do RuntimeGlue::with_task_handle_and_failing |me, failing| {
             if failing {
                 for x in self.notifier.mut_iter() {
-                    x.task_result = Some(Failure(UnwindReasonLinked));
+                    x.task_result = Some(Failure(UnwindMessageLinked));
                 }
                 // Take everybody down with us. After this point, every
                 // other task in the group will see 'tg' as none, which
@@ -380,7 +379,7 @@ pub fn new(chan: Chan<UnwindResult>) -> AutoNotify {
             notify_chan: chan,
 
             // Un-set above when taskgroup successfully made.
-            task_result: Some(Failure(UnwindReasonStr("AutoNotify::new()".into_send_str())))
+            task_result: Some(Failure(UnwindMessageStrStatic("AutoNotify::new()")))
         }
     }
 }
index 1900d9d58011e2f0431c7aa9a5bbf1f008a783cf..20563718a6c1fdd42cb0c647797c411990448c5c 100644 (file)
@@ -75,6 +75,11 @@ pub struct TyDesc {
 #[cfg(not(test))]
 pub enum Opaque { }
 
+#[cfg(stage0)]
+pub type Disr = int;
+#[cfg(not(stage0))]
+pub type Disr = u64;
+
 #[lang="ty_visitor"]
 #[cfg(not(test))]
 pub trait TyVisitor {
@@ -140,19 +145,19 @@ fn visit_leave_tup(&mut self, n_fields: uint,
                        sz: uint, align: uint) -> bool;
 
     fn visit_enter_enum(&mut self, n_variants: uint,
-                        get_disr: extern unsafe fn(ptr: *Opaque) -> int,
+                        get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
                         sz: uint, align: uint) -> bool;
     fn visit_enter_enum_variant(&mut self, variant: uint,
-                                disr_val: int,
+                                disr_val: Disr,
                                 n_fields: uint,
                                 name: &str) -> bool;
     fn visit_enum_variant_field(&mut self, i: uint, offset: uint, inner: *TyDesc) -> bool;
     fn visit_leave_enum_variant(&mut self, variant: uint,
-                                disr_val: int,
+                                disr_val: Disr,
                                 n_fields: uint,
                                 name: &str) -> bool;
     fn visit_leave_enum(&mut self, n_variants: uint,
-                        get_disr: extern unsafe fn(ptr: *Opaque) -> int,
+                        get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
                         sz: uint, align: uint) -> bool;
 
     fn visit_enter_fn(&mut self, purity: uint, proto: uint,
index 89126bf9c9c8823e3396916f0c421cedbee5a221..092e9b6d348bc150dcc815b5913e8cc4345cb72a 100644 (file)
@@ -19,7 +19,7 @@
 #[cold]
 #[lang="fail_"]
 pub fn fail_(expr: *c_char, file: *c_char, line: size_t) -> ! {
-    task::begin_unwind(expr, file, line);
+    task::begin_unwind_raw(expr, file, line);
 }
 
 #[cold]
index 46e80f9f4e8b79737de7b90cccd44e7df7e6bd9f..d784c1d38c60fd7193c2c95b1bf691c5b3ee302a 100644 (file)
@@ -62,3 +62,33 @@ impl Repr<*Box<String>> for @str {}
 
 // sure would be nice to have this
 // impl<T> Repr<*Vec<T>> for ~[T] {}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    use cast;
+
+    #[test]
+    fn synthesize_closure() {
+        unsafe {
+            let x = 10;
+            let f: &fn(int) -> int = |y| x + y;
+
+            assert_eq!(f(20), 30);
+
+            let original_closure: Closure = cast::transmute(f);
+
+            let actual_function_pointer = original_closure.code;
+            let environment = original_closure.env;
+
+            let new_closure = Closure {
+                code: actual_function_pointer,
+                env: environment
+            };
+
+            let new_f: &fn(int) -> int = cast::transmute(new_closure);
+            assert_eq!(new_f(20), 30);
+        }
+    }
+}
index 40b7ff29e241a45b2d1b7eefe7b9fd4140e5166b..7a5a326add40f8ac2010d48b188ede7a31d80e81 100644 (file)
@@ -14,7 +14,7 @@
 
 use ast;
 use ast::{Attribute, Attribute_, MetaItem, MetaWord, MetaNameValue, MetaList};
-use codemap::{Spanned, spanned, dummy_spanned};
+use codemap::{Span, Spanned, spanned, dummy_spanned};
 use codemap::BytePos;
 use diagnostic::span_handler;
 use parse::comments::{doc_comment_style, strip_doc_comment_decoration};
@@ -363,3 +363,115 @@ pub fn require_unique_names(diagnostic: @mut span_handler,
         }
     }
 }
+
+
+/**
+ * Fold this over attributes to parse #[repr(...)] forms.
+ *
+ * Valid repr contents: any of the primitive integral type names (see
+ * `int_type_of_word`, below) to specify the discriminant type; and `C`, to use
+ * the same discriminant size that the corresponding C enum would.  These are
+ * not allowed on univariant or zero-variant enums, which have no discriminant.
+ *
+ * If a discriminant type is so specified, then the discriminant will be
+ * present (before fields, if any) with that type; reprensentation
+ * optimizations which would remove it will not be done.
+ */
+pub fn find_repr_attr(diagnostic: @mut span_handler, attr: @ast::MetaItem, acc: ReprAttr)
+    -> ReprAttr {
+    let mut acc = acc;
+    match attr.node {
+        ast::MetaList(s, ref items) if "repr" == s => {
+            for item in items.iter() {
+                match item.node {
+                    ast::MetaWord(word) => {
+                        let hint = match word.as_slice() {
+                            // Can't use "extern" because it's not a lexical identifier.
+                            "C" => ReprExtern,
+                            _ => match int_type_of_word(word) {
+                                Some(ity) => ReprInt(item.span, ity),
+                                None => {
+                                    // Not a word we recognize
+                                    diagnostic.span_err(item.span,
+                                                        "unrecognized representation hint");
+                                    ReprAny
+                                }
+                            }
+                        };
+                        if hint != ReprAny {
+                            if acc == ReprAny {
+                                acc = hint;
+                            } else if acc != hint {
+                                diagnostic.span_warn(item.span,
+                                                     "conflicting representation hint ignored")
+                            }
+                        }
+                    }
+                    // Not a word:
+                    _ => diagnostic.span_err(item.span, "unrecognized representation hint")
+                }
+            }
+        }
+        // Not a "repr" hint: ignore.
+        _ => { }
+    }
+    return acc;
+}
+
+fn int_type_of_word(s: &str) -> Option<IntType> {
+    match s {
+        "i8" => Some(SignedInt(ast::ty_i8)),
+        "u8" => Some(UnsignedInt(ast::ty_u8)),
+        "i16" => Some(SignedInt(ast::ty_i16)),
+        "u16" => Some(UnsignedInt(ast::ty_u16)),
+        "i32" => Some(SignedInt(ast::ty_i32)),
+        "u32" => Some(UnsignedInt(ast::ty_u32)),
+        "i64" => Some(SignedInt(ast::ty_i64)),
+        "u64" => Some(UnsignedInt(ast::ty_u64)),
+        "int" => Some(SignedInt(ast::ty_i)),
+        "uint" => Some(UnsignedInt(ast::ty_u)),
+        _ => None
+    }
+}
+
+#[deriving(Eq)]
+pub enum ReprAttr {
+    ReprAny,
+    ReprInt(Span, IntType),
+    ReprExtern
+}
+
+impl ReprAttr {
+    pub fn is_ffi_safe(&self) -> bool {
+        match *self {
+            ReprAny => false,
+            ReprInt(_sp, ity) => ity.is_ffi_safe(),
+            ReprExtern => true
+        }
+    }
+}
+
+#[deriving(Eq)]
+pub enum IntType {
+    SignedInt(ast::int_ty),
+    UnsignedInt(ast::uint_ty)
+}
+
+impl IntType {
+    #[inline]
+    pub fn is_signed(self) -> bool {
+        match self {
+            SignedInt(*) => true,
+            UnsignedInt(*) => false
+        }
+    }
+    fn is_ffi_safe(self) -> bool {
+        match self {
+            SignedInt(ast::ty_i8) | UnsignedInt(ast::ty_u8) |
+            SignedInt(ast::ty_i16) | UnsignedInt(ast::ty_u16) |
+            SignedInt(ast::ty_i32) | UnsignedInt(ast::ty_u32) |
+            SignedInt(ast::ty_i64) | UnsignedInt(ast::ty_u64) => true,
+            _ => false
+        }
+    }
+}
index 273ce180a5f1dfccb33caba72a83b1fdbbac134a..76d9f755d3c9f64a86e1f929721846420be6fe21 100644 (file)
@@ -604,9 +604,9 @@ fn expr_fail(&self, span: Span, msg: @str) -> @ast::Expr {
             span,
             ~[
                 self.ident_of("std"),
-                self.ident_of("sys"),
-                self.ident_of("FailWithCause"),
-                self.ident_of("fail_with"),
+                self.ident_of("rt"),
+                self.ident_of("task"),
+                self.ident_of("begin_unwind"),
             ],
             ~[
                 self.expr_str(span, msg),
index 575f8bc6278c7065fc48877dffe97808d763fb6a..052b177d4d8d3f4d2f49e02803fddc4334fc4af4 100644 (file)
@@ -763,8 +763,7 @@ pub fn new_span(cx: @ExtCtxt, sp: Span) -> Span {
 // syntax elements.
 
 pub fn std_macros() -> @str {
-    return
-@"mod __std_macros {
+@r#"mod __std_macros {
     #[macro_escape];
     #[doc(hidden)];
 
@@ -789,31 +788,30 @@ macro_rules! debug( ($($arg:tt)*) => (
 
     macro_rules! fail(
         () => (
-            fail!(\"explicit failure\")
+            fail!("explicit failure")
         );
-        ($fmt:expr) => (
-            ::std::sys::FailWithCause::fail_with($fmt, file!(), line!())
+        ($msg:expr) => (
+            ::std::rt::task::begin_unwind($msg, file!(), line!())
         );
         ($fmt:expr, $($arg:tt)*) => (
-            ::std::sys::FailWithCause::fail_with(format!($fmt, $($arg)*), file!(), line!())
+            ::std::rt::task::begin_unwind(format!($fmt, $($arg)*), file!(), line!())
         )
     )
 
     macro_rules! assert(
         ($cond:expr) => {
             if !$cond {
-                ::std::sys::FailWithCause::fail_with(
-                    \"assertion failed: \" + stringify!($cond), file!(), line!())
+                fail!("assertion failed: {:s}", stringify!($cond))
             }
         };
         ($cond:expr, $msg:expr) => {
             if !$cond {
-                ::std::sys::FailWithCause::fail_with($msg, file!(), line!())
+                fail!($msg)
             }
         };
         ($cond:expr, $( $arg:expr ),+) => {
             if !$cond {
-                ::std::sys::FailWithCause::fail_with(format!( $($arg),+ ), file!(), line!())
+                fail!( $($arg),+ )
             }
         }
     )
@@ -826,9 +824,8 @@ macro_rules! assert_eq (
                 // check both directions of equality....
                 if !((*given_val == *expected_val) &&
                      (*expected_val == *given_val)) {
-                    fail!(\"assertion failed: `(left == right) && (right == \
-                             left)` (left: `{:?}`, right: `{:?}`)\",
-                           *given_val, *expected_val);
+                    fail!("assertion failed: `(left == right) && (right == left)` \
+                           (left: `{:?}`, right: `{:?}`)", *given_val, *expected_val)
                 }
             }
         )
@@ -846,7 +843,7 @@ macro_rules! assert_approx_eq (
                     given_val.approx_eq(&expected_val) &&
                     expected_val.approx_eq(&given_val)
                 ) {
-                    fail!(\"left: {:?} does not approximately equal right: {:?}\",
+                    fail!("left: {:?} does not approximately equal right: {:?}",
                            given_val, expected_val);
                 }
             }
@@ -863,42 +860,37 @@ macro_rules! assert_approx_eq (
                     given_val.approx_eq_eps(&expected_val, &epsilon_val) &&
                     expected_val.approx_eq_eps(&given_val, &epsilon_val)
                 ) {
-                    fail!(\"left: {:?} does not approximately equal right: \
-                             {:?} with epsilon: {:?}\",
+                    fail!("left: {:?} does not approximately equal right: \
+                             {:?} with epsilon: {:?}",
                           given_val, expected_val, epsilon_val);
                 }
             }
         )
     )
 
-    // FIXME(#6266): change the /* to /** when attributes are supported on macros
-    // (Though even then—is it going to work according to the clear intent here?)
-    /*
-    A utility macro for indicating unreachable code. It will fail if
-    executed. This is occasionally useful to put after loops that never
-    terminate normally, but instead directly return from a function.
-
-    # Example
-
-    ```rust
-    fn choose_weighted_item(v: &[Item]) -> Item {
-        assert!(!v.is_empty());
-        let mut so_far = 0u;
-        for v.each |item| {
-            so_far += item.weight;
-            if so_far > 100 {
-                return item;
-            }
-        }
-        // The above loop always returns, so we must hint to the
-        // type checker that it isn't possible to get down here
-        unreachable!();
-    }
-    ```
-
-    */
+    /// A utility macro for indicating unreachable code. It will fail if
+    /// executed. This is occasionally useful to put after loops that never
+    /// terminate normally, but instead directly return from a function.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// fn choose_weighted_item(v: &[Item]) -> Item {
+    ///     assert!(!v.is_empty());
+    ///     let mut so_far = 0u;
+    ///     for item in v.iter() {
+    ///         so_far += item.weight;
+    ///         if so_far > 100 {
+    ///             return item;
+    ///         }
+    ///     }
+    ///     // The above loop always returns, so we must hint to the
+    ///     // type checker that it isn't possible to get down here
+    ///     unreachable!();
+    /// }
+    /// ```
     macro_rules! unreachable (() => (
-        fail!(\"internal error: entered unreachable code\");
+        fail!("internal error: entered unreachable code");
     ))
 
     macro_rules! condition (
@@ -968,18 +960,18 @@ macro_rules! local_data_key (
         )
     )
 
-    // externfn! declares a wrapper for an external function.
-    // It is intended to be used like:
-    //
-    // externfn!(#[nolink]
-    //           fn memcmp(cx: *u8, ct: *u8, n: u32) -> u32)
-    //
-    // Due to limitations in the macro parser, this pattern must be
-    // implemented with 4 distinct patterns (with attrs / without
-    // attrs CROSS with args / without ARGS).
-    //
-    // Also, this macro grammar allows for any number of return types
-    // because I couldn't figure out the syntax to specify at most one.
+    /// externfn! declares a wrapper for an external function.
+    /// It is intended to be used like:
+    ///
+    /// externfn!(#[nolink]
+    ///           fn memcmp(cx: *u8, ct: *u8, n: u32) -> u32)
+    ///
+    /// Due to limitations in the macro parser, this pattern must be
+    /// implemented with 4 distinct patterns (with attrs / without
+    /// attrs CROSS with args / without ARGS).
+    ///
+    /// Also, this macro grammar allows for any number of return types
+    /// because I couldn't figure out the syntax to specify at most one.
     macro_rules! externfn(
         (fn $name:ident () $(-> $ret_ty:ty),*) => (
             pub unsafe fn $name() $(-> $ret_ty),* {
@@ -1045,7 +1037,7 @@ pub unsafe fn $name($($arg_name : $arg_ty),*) $(-> $ret_ty),* {
         )
     )
 
-}";
+}"#
 }
 
 struct Injector {
index 7ccb06a3296f4ced2905c390e120e949e6b8f317..e7648a081be35cb22d8d3e7b8b0ba1ebf05115ca 100644 (file)
@@ -26,34 +26,6 @@ typedef int _Unwind_Action;
 struct _Unwind_Context;
 struct _Unwind_Exception;
 
-typedef void (*CDECL stack_switch_shim)(void*);
-
-/**********************************************************************
- * Switches to the C-stack and invokes |fn_ptr|, passing |args| as argument.
- * This is used by the C compiler to call foreign functions and by other
- * upcalls to switch to the C stack.  The return value is passed through a
- * field in the args parameter. This upcall is specifically for switching
- * to the shim functions generated by rustc.
- */
-extern "C" CDECL void
-upcall_call_shim_on_c_stack(void *args, void *fn_ptr) {
-    stack_switch_shim f = (stack_switch_shim)fn_ptr;
-    f(args);
-}
-
-/*
- * The opposite of above. Starts on a C stack and switches to the Rust
- * stack. This is the only upcall that runs from the C stack.
- */
-extern "C" CDECL void
-upcall_call_shim_on_rust_stack(void *args, void *fn_ptr) {
-    // There's no task. Call the function and hope for the best
-    stack_switch_shim f = (stack_switch_shim)fn_ptr;
-    f(args);
-}
-
-/**********************************************************************/
-
 #ifdef __SEH__
 #  define PERSONALITY_FUNC __gxx_personality_seh0
 #else
@@ -107,19 +79,6 @@ upcall_rust_personality(int version,
     return args.retval;
 }
 
-// NB: This needs to be blazing fast. Don't switch stacks
-extern "C" CDECL void *
-upcall_new_stack(size_t stk_sz, void *args_addr, size_t args_sz) {
-    assert(false && "newsched shouldn't be growing the stack");
-    return NULL;
-}
-
-// NB: This needs to be blazing fast. Don't switch stacks
-extern "C" CDECL void
-upcall_del_stack() {
-    assert(false && "newsched shouldn't be growing the stack");
-}
-
 // Landing pads need to call this to insert the
 // correct limit into TLS.
 // NB: This must run on the Rust stack because it
index 47c9554daa0189c95a49e6f3224e4cb287bde0cc..60e4d3abd7a3259ff1eafc12e014c3b5510bc62e 100644 (file)
@@ -25,10 +25,6 @@ rust_win32_rand_acquire
 rust_win32_rand_gen
 rust_win32_rand_release
 upcall_rust_personality
-upcall_call_shim_on_c_stack
-upcall_call_shim_on_rust_stack
-upcall_new_stack
-upcall_del_stack
 upcall_reset_stack_limit
 rust_uv_loop_new
 rust_uv_loop_delete
index a78153523d2529bde99ccaf83b2de4da7366fb33..7223d1871376498aa4b2645ab0477e2266835b24 100644 (file)
@@ -63,12 +63,3 @@ rust_thread::join() {
 #endif
    thread = 0;
 }
-
-void
-rust_thread::detach() {
-#if !defined(__WIN32__)
-    // Don't leak pthread resources.
-    // http://crosstantine.blogspot.com/2010/01/pthreadcreate-memory-leak.html
-    CHECKED(pthread_detach(thread));
-#endif
-}
index cad87e514b5c831f9f24d3d26738125dd1605059..257eefceb433a95ae7db0980b449c8b06ffda700 100644 (file)
@@ -33,7 +33,6 @@ class rust_thread {
     virtual void run() = 0;
 
     void join();
-    void detach();
 };
 
 #endif /* RUST_THREAD_H */
diff --git a/src/rt/util/array_list.h b/src/rt/util/array_list.h
deleted file mode 100644 (file)
index 0852cf9..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-// 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.
-
-#ifndef ARRAY_LIST_H
-#define ARRAY_LIST_H
-
-#include <inttypes.h>
-#include <stddef.h>
-#include <new>
-
-/**
- * A simple, resizable array list. Note that this only works with POD types
- * (because data is grown via realloc).
- */
-template<typename T> class array_list {
-    static const size_t INITIAL_CAPACITY = 8;
-    size_t _size;
-    T * _data;
-    size_t _capacity;
-private:
-    // private and left undefined to disable copying
-    array_list(const array_list& rhs);
-    array_list& operator=(const array_list& rhs);
-public:
-    array_list();
-    ~array_list();
-    size_t size() const;
-    int32_t append(T value);
-    int32_t push(T value);
-    void pop(T *value);
-    bool replace(T old_value, T new_value);
-    int32_t index_of(T value) const;
-    bool is_empty() const;
-    T* data();
-    const T* data() const;
-    T & operator[](size_t index);
-    const T & operator[](size_t index) const;
-};
-
-template<typename T>
-array_list<T>::array_list() {
-    _size = 0;
-    _capacity = INITIAL_CAPACITY;
-    _data = (T *) malloc(sizeof(T) * _capacity);
-}
-
-template<typename T>
-array_list<T>::~array_list() {
-    free(_data);
-}
-
-template<typename T> size_t
-array_list<T>::size() const {
-    return _size;
-}
-
-template<typename T> int32_t
-array_list<T>::append(T value) {
-    return push(value);
-}
-
-template<typename T> int32_t
-array_list<T>::push(T value) {
-    if (_size == _capacity) {
-        size_t new_capacity = _capacity * 2;
-        void* buffer = realloc(_data, new_capacity * sizeof(T));
-        if (buffer == NULL) {
-            fprintf(stderr,
-                    "array_list::push> "
-                    "Out of memory allocating %ld bytes",
-                    (long int) (new_capacity * sizeof(T)));
-            abort();
-        }
-        _data = (T *) buffer;
-        _capacity = new_capacity;
-    }
-    _data[_size ++] = value;
-    return _size - 1;
-}
-
-template<typename T> void
-array_list<T>::pop(T *value) {
-    assert(_size > 0);
-    if (value != NULL) {
-        *value = _data[-- _size];
-    } else {
-        -- _size;
-    }
-}
-
-/**
- * Replaces the old_value in the list with the new_value.
- * Returns the true if the replacement succeeded, or false otherwise.
- */
-template<typename T> bool
-array_list<T>::replace(T old_value, T new_value) {
-    int index = index_of(old_value);
-    if (index < 0) {
-        return false;
-    }
-    _data[index] = new_value;
-    return true;
-}
-
-template<typename T> int32_t
-array_list<T>::index_of(T value) const {
-    for (size_t i = 0; i < _size; i++) {
-        if (_data[i] == value) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-template<typename T> T &
-array_list<T>::operator[](size_t index) {
-    assert(index < size());
-    return _data[index];
-}
-
-template<typename T> const T &
-array_list<T>::operator[](size_t index) const {
-    assert(index < size());
-    return _data[index];
-}
-
-template<typename T> bool
-array_list<T>::is_empty() const {
-    return _size == 0;
-}
-
-template<typename T> T*
-array_list<T>::data() {
-    return _data;
-}
-
-template<typename T> const T*
-array_list<T>::data() const {
-    return _data;
-}
-
-#endif /* ARRAY_LIST_H */
index a749597a3f0b5cc845f2cfe33e66d073be58cc78..7a12e2fd60d95eda4569e16c08b6f8c76256c59b 100644 (file)
@@ -1,3 +1,11 @@
+S 2013-10-29 fed48cc
+  freebsd-x86_64 4a43216b432511a5fd6b727753aedb749f6a68dc
+  linux-i386 53f65d4b1377c17fc12d05d7c4a0fbd92eea071f
+  linux-x86_64 afa5f19a37a2cf137e5d4277951fa07efda8e072
+  macos-i386 7522c24f78ed35020e2877e3eada058ea8a11f35
+  macos-x86_64 a18afdcbbdbb81c1fdf08788b24f0d3ea8701eb1
+  winnt-i386 c78f0839c9524eda33c54a5232121886021b5352
+
 S 2013-10-28 2ab4a6f
   freebsd-x86_64 08af04bcf739930bdb7d0ad244b2c8094cd5096a
   linux-i386 c233de1ed09872d5c7a3e1ce9ab9eb6e16631201
index 5d4ddec17f5054ea9a3443f079816e3a3e965699..1be66efb203550084aaed10067927ecf5092aa99 100644 (file)
@@ -9,81 +9,77 @@
 // except according to those terms.
 
 extern mod extra;
+
+use std::iter::range_step;
 use extra::arena::Arena;
+use extra::future::Future;
 
 enum Tree<'self> {
     Nil,
-    Node(&'self Tree<'self>, &'self Tree<'self>, int),
+    Node(&'self Tree<'self>, &'self Tree<'self>, int)
 }
 
 fn item_check(t: &Tree) -> int {
     match *t {
-      Nil => { return 0; }
-      Node(left, right, item) => {
-        return item + item_check(left) - item_check(right);
-      }
+        Nil => 0,
+        Node(l, r, i) => i + item_check(l) - item_check(r)
     }
 }
 
-fn bottom_up_tree<'r>(arena: &'r Arena, item: int, depth: int)
-                   -> &'r Tree<'r> {
+fn bottom_up_tree<'r>(arena: &'r Arena, item: int, depth: int) -> &'r Tree<'r> {
     if depth > 0 {
-        return arena.alloc(
-            || Node(bottom_up_tree(arena, 2 * item - 1, depth - 1),
-                    bottom_up_tree(arena, 2 * item, depth - 1),
-                    item));
-    }
-    return arena.alloc(|| Nil);
+        do arena.alloc {
+            Node(bottom_up_tree(arena, 2 * item - 1, depth - 1),
+                 bottom_up_tree(arena, 2 * item, depth - 1),
+                 item)
+        }
+    } else {arena.alloc(|| Nil)}
 }
 
 fn main() {
-    use std::os;
-    use std::int;
     let args = std::os::args();
-    let args = if os::getenv("RUST_BENCH").is_some() {
-        ~[~"", ~"17"]
+    let n = if std::os::getenv("RUST_BENCH").is_some() {
+        17
     } else if args.len() <= 1u {
-        ~[~"", ~"8"]
+        8
     } else {
-        args
+        from_str(args[1]).unwrap()
     };
-
-    let n = from_str::<int>(args[1]).unwrap();
     let min_depth = 4;
-    let mut max_depth;
-    if min_depth + 2 > n {
-        max_depth = min_depth + 2;
-    } else {
-        max_depth = n;
-    }
+    let max_depth = if min_depth + 2 > n {min_depth + 2} else {n};
 
-    let stretch_arena = Arena::new();
-    let stretch_depth = max_depth + 1;
-    let stretch_tree = bottom_up_tree(&stretch_arena, 0, stretch_depth);
+    {
+        let arena = Arena::new();
+        let depth = max_depth + 1;
+        let tree = bottom_up_tree(&arena, 0, depth);
 
-    println!("stretch tree of depth {}\t check: {}",
-              stretch_depth,
-              item_check(stretch_tree));
+        println!("stretch tree of depth {}\t check: {}",
+                 depth, item_check(tree));
+    }
 
     let long_lived_arena = Arena::new();
     let long_lived_tree = bottom_up_tree(&long_lived_arena, 0, max_depth);
-    let mut depth = min_depth;
-    while depth <= max_depth {
-        let iterations = int::pow(2, (max_depth - depth + min_depth) as uint);
-        let mut chk = 0;
-        let mut i = 1;
-        while i <= iterations {
-            let mut temp_tree = bottom_up_tree(&long_lived_arena, i, depth);
-            chk += item_check(temp_tree);
-            temp_tree = bottom_up_tree(&long_lived_arena, -i, depth);
-            chk += item_check(temp_tree);
-            i += 1;
-        }
-        println!("{}\t trees of depth {}\t check: {}",
-                  iterations * 2, depth, chk);
-        depth += 2;
+
+    let mut messages = range_step(min_depth, max_depth + 1, 2).map(|depth| {
+            use std::int::pow;
+            let iterations = pow(2, (max_depth - depth + min_depth) as uint);
+            do Future::spawn {
+                let mut chk = 0;
+                for i in range(1, iterations + 1) {
+                    let arena = Arena::new();
+                    let a = bottom_up_tree(&arena, i, depth);
+                    let b = bottom_up_tree(&arena, -i, depth);
+                    chk += item_check(a) + item_check(b);
+                }
+                format!("{}\t trees of depth {}\t check: {}",
+                        iterations * 2, depth, chk)
+            }
+        }).to_owned_vec();
+
+    for message in messages.mut_iter() {
+        println(*message.get_ref());
     }
+
     println!("long lived tree of depth {}\t check: {}",
-              max_depth,
-              item_check(long_lived_tree));
+             max_depth, item_check(long_lived_tree));
 }
diff --git a/src/test/compile-fail/bad-expr-lhs.rs b/src/test/compile-fail/bad-expr-lhs.rs
new file mode 100644 (file)
index 0000000..6907bf4
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    1 = 2; //~ ERROR illegal left-hand side expression
+    1 += 2; //~ ERROR illegal left-hand side expression
+    (1, 2) = (3, 4); //~ ERROR illegal left-hand side expression
+
+    let (a, b) = (1, 2);
+    (a, b) = (3, 4); //~ ERROR illegal left-hand side expression
+
+    None = Some(3); //~ ERROR illegal left-hand side expression
+}
index f0dc28b736d1668f8e3f86634f26660d6be5225c..c0fb24c83e37af9c27dfe4e893f5021acdc06364 100644 (file)
@@ -12,6 +12,5 @@
 
 fn main() {
     // assigning to various global constants
-    None = Some(3); //~ ERROR cannot assign to immutable static item
     foo = 6; //~ ERROR cannot assign to immutable static item
 }
diff --git a/src/test/compile-fail/enum-discrim-too-small.rs b/src/test/compile-fail/enum-discrim-too-small.rs
new file mode 100644 (file)
index 0000000..2de50ad
--- /dev/null
@@ -0,0 +1,58 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[repr(u8)] //~ NOTE discriminant type specified here
+enum Eu8 {
+    Au8 = 23,
+    Bu8 = 223,
+    Cu8 = -23, //~ ERROR discriminant value outside specified type
+}
+
+#[repr(i8)] //~ NOTE discriminant type specified here
+enum Ei8 {
+    Ai8 = 23,
+    Bi8 = -23,
+    Ci8 = 223, //~ ERROR discriminant value outside specified type
+}
+
+#[repr(u16)] //~ NOTE discriminant type specified here
+enum Eu16 {
+    Au16 = 23,
+    Bu16 = 55555,
+    Cu16 = -22333, //~ ERROR discriminant value outside specified type
+}
+
+#[repr(i16)] //~ NOTE discriminant type specified here
+enum Ei16 {
+    Ai16 = 23,
+    Bi16 = -22333,
+    Ci16 = 55555, //~ ERROR discriminant value outside specified type
+}
+
+#[repr(u32)] //~ NOTE discriminant type specified here
+enum Eu32 {
+    Au32 = 23,
+    Bu32 = 3_000_000_000,
+    Cu32 = -2_000_000_000, //~ ERROR discriminant value outside specified type
+}
+
+#[repr(i32)] //~ NOTE discriminant type specified here
+enum Ei32 {
+    Ai32 = 23,
+    Bi32 = -2_000_000_000,
+    Ci32 = 3_000_000_000, //~ ERROR discriminant value outside specified type
+}
+
+// u64 currently allows negative numbers, and i64 allows numbers greater than `1<<63`.  This is a
+// little counterintuitive, but since the discriminant can store all the bits, and extracting it
+// with a cast requires specifying the signedness, there is no loss of information in those cases.
+// This also applies to int and uint on 64-bit targets.
+
+pub fn main() { }
diff --git a/src/test/compile-fail/fail-expr.rs b/src/test/compile-fail/fail-expr.rs
deleted file mode 100644 (file)
index 98270bd..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// 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.
-
-// error-pattern:failed to find an implementation of trait std::sys::FailWithCause for int
-
-fn main() { fail!(5); }
diff --git a/src/test/compile-fail/fail-type-err.rs b/src/test/compile-fail/fail-type-err.rs
deleted file mode 100644 (file)
index b675524..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// 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.
-
-// error-pattern:failed to find an implementation of trait std::sys::FailWithCause for ~[int]
-fn main() { fail!(~[0i]); }
diff --git a/src/test/compile-fail/lint-ctypes-enum.rs b/src/test/compile-fail/lint-ctypes-enum.rs
new file mode 100644 (file)
index 0000000..857e3bb
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[deny(ctypes)];
+
+enum Z { }
+enum U { A }
+enum B { C, D }
+enum T { E, F, G }
+
+extern {
+   fn zf(x: Z);
+   fn uf(x: U);
+   fn bf(x: B); //~ ERROR found enum type without foreign-function-safe
+   fn tf(x: T); //~ ERROR found enum type without foreign-function-safe
+}
+
+pub fn main() { }
index a5f85a685e6958ce63b639bdd39956db3b3730b0..d0608ec4c19273db2eab7f7c85ad94260e77b03d 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//error-pattern:discriminator value already exists
+//error-pattern:discriminant value already exists
 
 // black and white have the same discriminator value ...
 
index 2f02844fdc5f704b14dc9217273dc63e4097c744..a6aacdf8e665ab59cbf3654db4f2386c2724f394 100644 (file)
@@ -15,7 +15,7 @@
 // STACK BY REF
 // debugger:finish
 // debugger:print *self
-// check:$1 = {{Variant2, x = 1799, y = 1799}, {Variant2, 117901063}}
+// check:$1 = {{Variant2, [...]}, {Variant2, 117901063}}
 // debugger:print arg1
 // check:$2 = -1
 // debugger:print arg2
@@ -25,7 +25,7 @@
 // STACK BY VAL
 // debugger:finish
 // d ebugger:print self -- ignored for now because of issue #8512
-// c heck:$X = {{Variant2, x = 1799, y = 1799}, {Variant2, 117901063}}
+// c heck:$X = {{Variant2, [...]}, {Variant2, 117901063}}
 // debugger:print arg1
 // check:$4 = -3
 // debugger:print arg2
@@ -35,7 +35,7 @@
 // OWNED BY REF
 // debugger:finish
 // debugger:print *self
-// check:$6 = {{Variant1, x = 1799, y = 1799}, {Variant1, 117901063}}
+// check:$6 = {{Variant1, x = 1799, y = 1799}, {Variant1, [...]}}
 // debugger:print arg1
 // check:$7 = -5
 // debugger:print arg2
@@ -45,7 +45,7 @@
 // OWNED BY VAL
 // debugger:finish
 // d ebugger:print self -- ignored for now because of issue #8512
-// c heck:$X = {{Variant1, x = 1799, y = 1799}, {Variant1, 117901063}}
+// c heck:$X = {{Variant1, x = 1799, y = 1799}, {Variant1, [...]}}
 // debugger:print arg1
 // check:$9 = -7
 // debugger:print arg2
@@ -55,7 +55,7 @@
 // OWNED MOVED
 // debugger:finish
 // debugger:print *self
-// check:$11 = {{Variant1, x = 1799, y = 1799}, {Variant1, 117901063}}
+// check:$11 = {{Variant1, x = 1799, y = 1799}, {Variant1, [...]}}
 // debugger:print arg1
 // check:$12 = -9
 // debugger:print arg2
@@ -65,7 +65,7 @@
 // MANAGED BY REF
 // debugger:finish
 // debugger:print *self
-// check:$14 = {{Variant2, x = 1799, y = 1799}, {Variant2, 117901063}}
+// check:$14 = {{Variant2, [...]}, {Variant2, 117901063}}
 // debugger:print arg1
 // check:$15 = -11
 // debugger:print arg2
@@ -75,7 +75,7 @@
 // MANAGED BY VAL
 // debugger:finish
 // d ebugger:print self -- ignored for now because of issue #8512
-// c heck:$X = {{Variant2, x = 1799, y = 1799}, {Variant2, 117901063}}
+// c heck:$X = {{Variant2, [...]}, {Variant2, 117901063}}
 // debugger:print arg1
 // check:$17 = -13
 // debugger:print arg2
@@ -85,7 +85,7 @@
 // MANAGED SELF
 // debugger:finish
 // debugger:print self->val
-// check:$19 = {{Variant2, x = 1799, y = 1799}, {Variant2, 117901063}}
+// check:$19 = {{Variant2, [...]}, {Variant2, 117901063}}
 // debugger:print arg1
 // check:$20 = -15
 // debugger:print arg2
diff --git a/src/test/run-fail/fail-macro-send_str.rs b/src/test/run-fail/fail-macro-send_str.rs
deleted file mode 100644 (file)
index 2047fde..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 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.
-
-// error-pattern:failed at 'test-fail-send-str'
-
-fn main() {
-    fail!("test-fail-send-str".into_send_str());
-}
diff --git a/src/test/run-pass/enum-discrim-autosizing.rs b/src/test/run-pass/enum-discrim-autosizing.rs
new file mode 100644 (file)
index 0000000..ef34115
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::mem::size_of;
+
+enum Ei8 {
+    Ai8 = -1,
+    Bi8 = 0
+}
+
+enum Eu8 {
+    Au8 = 0,
+    Bu8 = 0x80
+}
+
+enum Ei16 {
+    Ai16 = -1,
+    Bi16 = 0x80
+}
+
+enum Eu16 {
+    Au16 = 0,
+    Bu16 = 0x8000
+}
+
+enum Ei32 {
+    Ai32 = -1,
+    Bi32 = 0x8000
+}
+
+enum Eu32 {
+    Au32 = 0,
+    Bu32 = 0x8000_0000
+}
+
+enum Ei64 {
+    Ai64 = -1,
+    Bi64 = 0x8000_0000
+}
+
+enum Eu64 {
+    Au64 = 0,
+    Bu64 = 0x8000_0000_0000_0000
+}
+
+pub fn main() {
+    assert_eq!(size_of::<Ei8>(), 1);
+    assert_eq!(size_of::<Eu8>(), 1);
+    assert_eq!(size_of::<Ei16>(), 2);
+    assert_eq!(size_of::<Eu16>(), 2);
+    assert_eq!(size_of::<Ei32>(), 4);
+    assert_eq!(size_of::<Eu32>(), 4);
+    assert_eq!(size_of::<Ei64>(), 8);
+    assert_eq!(size_of::<Eu64>(), 8);
+}
diff --git a/src/test/run-pass/enum-discrim-manual-sizing.rs b/src/test/run-pass/enum-discrim-manual-sizing.rs
new file mode 100644 (file)
index 0000000..16eaac0
--- /dev/null
@@ -0,0 +1,84 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::mem::size_of;
+
+#[repr(i8)]
+enum Ei8 {
+    Ai8 = 0,
+    Bi8 = 1
+}
+
+#[repr(u8)]
+enum Eu8 {
+    Au8 = 0,
+    Bu8 = 1
+}
+
+#[repr(i16)]
+enum Ei16 {
+    Ai16 = 0,
+    Bi16 = 1
+}
+
+#[repr(u16)]
+enum Eu16 {
+    Au16 = 0,
+    Bu16 = 1
+}
+
+#[repr(i32)]
+enum Ei32 {
+    Ai32 = 0,
+    Bi32 = 1
+}
+
+#[repr(u32)]
+enum Eu32 {
+    Au32 = 0,
+    Bu32 = 1
+}
+
+#[repr(i64)]
+enum Ei64 {
+    Ai64 = 0,
+    Bi64 = 1
+}
+
+#[repr(u64)]
+enum Eu64 {
+    Au64 = 0,
+    Bu64 = 1
+}
+
+#[repr(int)]
+enum Eint {
+    Aint = 0,
+    Bint = 1
+}
+
+#[repr(uint)]
+enum Euint {
+    Auint = 0,
+    Buint = 1
+}
+
+pub fn main() {
+    assert_eq!(size_of::<Ei8>(), 1);
+    assert_eq!(size_of::<Eu8>(), 1);
+    assert_eq!(size_of::<Ei16>(), 2);
+    assert_eq!(size_of::<Eu16>(), 2);
+    assert_eq!(size_of::<Ei32>(), 4);
+    assert_eq!(size_of::<Eu32>(), 4);
+    assert_eq!(size_of::<Ei64>(), 8);
+    assert_eq!(size_of::<Eu64>(), 8);
+    assert_eq!(size_of::<Eint>(), size_of::<int>());
+    assert_eq!(size_of::<Euint>(), size_of::<uint>());
+}
index 65f93b1c3c2e0f4a92a7d4e0612e7386b913cc3a..6a0110436b3c86a9e99082cd72990908cfab8eda 100644 (file)
@@ -8,18 +8,48 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::mem;
+#[feature(macro_rules)];
+
+macro_rules! check {
+    ($m:ident, $t:ty, $v:expr) => {{
+        mod $m {
+            use std::mem::size_of;
+            enum E {
+                V = $v,
+                A = 0
+            }
+            static C: E = V;
+            pub fn check() {
+                assert_eq!(size_of::<E>(), size_of::<$t>());
+                assert_eq!(V as $t, $v);
+                assert_eq!(C as $t, $v);
+                assert_eq!(format!("{:?}", V), ~"V");
+                assert_eq!(format!("{:?}", C), ~"V");
+            }
+        }
+        $m::check();
+    }}
+}
 
 pub fn main() {
-    enum E { V = 0x1717171717171717 }
-    static C: E = V;
-    let expected: u64 = if mem::size_of::<uint>() < 8 {
-        0x17171717
-    } else {
-        0x1717171717171717
-    };
-    assert_eq!(expected, V as u64);
-    assert_eq!(expected, C as u64);
-    assert_eq!(format!("{:?}", V), ~"V");
-    assert_eq!(format!("{:?}", C), ~"V");
+    check!(a, u8, 0x17);
+    check!(b, u8, 0xe8);
+    check!(c, u16, 0x1727);
+    check!(d, u16, 0xe8d8);
+    check!(e, u32, 0x17273747);
+    check!(f, u32, 0xe8d8c8b8);
+    check!(g, u64, 0x1727374757677787u64);
+    check!(h, u64, 0xe8d8c8b8a8988878u64);
+
+    check!(z, i8, 0x17);
+    check!(y, i8, -0x17);
+    check!(x, i16, 0x1727);
+    check!(w, i16, -0x1727);
+    check!(v, i32, 0x17273747);
+    check!(u, i32, -0x17273747);
+    check!(t, i64, 0x1727374757677787);
+    check!(s, i64, -0x1727374757677787);
+
+    enum Simple { A, B }
+    assert_eq!(::std::mem::size_of::<Simple>(), 1);
 }
index 7cebfa13223475f1702a3c8e3d1a199dd44f3732..3bedbfa27b7cae332b7f52d400877dd3dc6342d5 100644 (file)
@@ -27,6 +27,7 @@ pub struct Stuff<T> {
     }
 
     #[deriving(Eq)]
+    #[repr(int)]
     pub enum state {
         empty,
         full,
index 9901f7493f7acea7e0969f0625be12708e26350c..de8d9470f102716f0d7957d2f436db20b7b59fdc 100644 (file)
@@ -15,7 +15,7 @@
 use std::libc::c_void;
 use std::ptr;
 use std::mem;
-use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Opaque};
+use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Disr, Opaque};
 use std::unstable::raw::Vec;
 
 #[doc = "High-level interfaces to `std::unstable::intrinsics::visit_ty` reflection system."]
@@ -380,7 +380,7 @@ fn visit_leave_fn(&mut self, purity: uint, proto: uint,
     }
 
     fn visit_enter_enum(&mut self, n_variants: uint,
-                        get_disr: extern unsafe fn(ptr: *Opaque) -> int,
+                        get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
                         sz: uint, align: uint)
                      -> bool {
         self.align(align);
@@ -389,7 +389,7 @@ fn visit_enter_enum(&mut self, n_variants: uint,
     }
 
     fn visit_enter_enum_variant(&mut self, variant: uint,
-                                disr_val: int,
+                                disr_val: Disr,
                                 n_fields: uint,
                                 name: &str) -> bool {
         if ! self.inner.visit_enter_enum_variant(variant, disr_val,
@@ -405,7 +405,7 @@ fn visit_enum_variant_field(&mut self, i: uint, offset: uint, inner: *TyDesc) ->
     }
 
     fn visit_leave_enum_variant(&mut self, variant: uint,
-                                disr_val: int,
+                                disr_val: Disr,
                                 n_fields: uint,
                                 name: &str) -> bool {
         if ! self.inner.visit_leave_enum_variant(variant, disr_val,
@@ -416,7 +416,7 @@ fn visit_leave_enum_variant(&mut self, variant: uint,
     }
 
     fn visit_leave_enum(&mut self, n_variants: uint,
-                        get_disr: extern unsafe fn(ptr: *Opaque) -> int,
+                        get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
                         sz: uint, align: uint)
                      -> bool {
         if ! self.inner.visit_leave_enum(n_variants, get_disr, sz, align) { return false; }
@@ -578,24 +578,24 @@ fn visit_leave_tup(&mut self, _n_fields: uint,
                        _sz: uint, _align: uint) -> bool { true }
 
     fn visit_enter_enum(&mut self, _n_variants: uint,
-                        _get_disr: extern unsafe fn(ptr: *Opaque) -> int,
+                        _get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
                         _sz: uint, _align: uint) -> bool {
         // FIXME (#3732): this needs to rewind between enum variants, or something.
         true
     }
     fn visit_enter_enum_variant(&mut self, _variant: uint,
-                                _disr_val: int,
+                                _disr_val: Disr,
                                 _n_fields: uint,
                                 _name: &str) -> bool { true }
     fn visit_enum_variant_field(&mut self, _i: uint, _offset: uint, inner: *TyDesc) -> bool {
         self.visit_inner(inner)
     }
     fn visit_leave_enum_variant(&mut self, _variant: uint,
-                                _disr_val: int,
+                                _disr_val: Disr,
                                 _n_fields: uint,
                                 _name: &str) -> bool { true }
     fn visit_leave_enum(&mut self, _n_variants: uint,
-                        _get_disr: extern unsafe fn(ptr: *Opaque) -> int,
+                        _get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
                         _sz: uint, _align: uint) -> bool { true }
 
     fn visit_enter_fn(&mut self, _purity: uint, _proto: uint,
index db68ee2b5002bf43f11300395fc4e8e3baafc907..e77cb432c3ad0c7567a601a55b38b2df67740832 100644 (file)
@@ -10,7 +10,7 @@
 
 #[feature(managed_boxes)];
 
-use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Opaque};
+use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Disr, Opaque};
 
 struct MyVisitor {
     types: @mut ~[~str],
@@ -114,22 +114,22 @@ fn visit_leave_tup(&mut self, _n_fields: uint,
                        _sz: uint, _align: uint) -> bool { true }
 
     fn visit_enter_enum(&mut self, _n_variants: uint,
-                        _get_disr: extern unsafe fn(ptr: *Opaque) -> int,
+                        _get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
                         _sz: uint, _align: uint) -> bool { true }
     fn visit_enter_enum_variant(&mut self,
                                 _variant: uint,
-                                _disr_val: int,
+                                _disr_val: Disr,
                                 _n_fields: uint,
                                 _name: &str) -> bool { true }
     fn visit_enum_variant_field(&mut self, _i: uint, _offset: uint, _inner: *TyDesc) -> bool { true }
     fn visit_leave_enum_variant(&mut self,
                                 _variant: uint,
-                                _disr_val: int,
+                                _disr_val: Disr,
                                 _n_fields: uint,
                                 _name: &str) -> bool { true }
     fn visit_leave_enum(&mut self,
                         _n_variants: uint,
-                        _get_disr: extern unsafe fn(ptr: *Opaque) -> int,
+                        _get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
                         _sz: uint, _align: uint) -> bool { true }
 
     fn visit_enter_fn(&mut self, _purity: uint, _proto: uint,
diff --git a/src/test/run-pass/small-enum-range-edge.rs b/src/test/run-pass/small-enum-range-edge.rs
new file mode 100644 (file)
index 0000000..a9fc134
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2013 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 the range assertion wraparound case in trans::middle::adt::load_discr.
+ */
+
+#[repr(u8)]
+enum Eu { Lu = 0, Hu = 255 }
+static CLu: Eu = Lu;
+static CHu: Eu = Hu;
+
+#[repr(i8)]
+enum Es { Ls = -128, Hs = 127 }
+static CLs: Es = Ls;
+static CHs: Es = Hs;
+
+pub fn main() {
+    assert_eq!((Hu as u8) + 1, Lu as u8);
+    assert_eq!((Hs as i8) + 1, Ls as i8);
+    assert_eq!(CLu as u8, Lu as u8);
+    assert_eq!(CHu as u8, Hu as u8);
+    assert_eq!(CLs as i8, Ls as i8);
+    assert_eq!(CHs as i8, Hs as i8);
+}
diff --git a/src/test/run-pass/small-enums-with-fields.rs b/src/test/run-pass/small-enums-with-fields.rs
new file mode 100644 (file)
index 0000000..c4f4b5e
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2013 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(macro_rules)];
+
+use std::mem::size_of;
+
+macro_rules! check {
+    ($t:ty, $sz:expr, $($e:expr, $s:expr),*) => {{
+        assert_eq!(size_of::<$t>(), $sz);
+        $({
+            static S: $t = $e;
+            let v: $t = $e;
+            assert_eq!(S, v);
+            assert_eq!(format!("{:?}", v), ~$s);
+            assert_eq!(format!("{:?}", S), ~$s);
+        });*
+    }}
+}
+
+pub fn main() {
+    check!(Option<u8>, 2,
+           None, "None",
+           Some(129u8), "Some(129u8)");
+    check!(Option<i16>, 4,
+           None, "None",
+           Some(-20000i16), "Some(-20000i16)");
+    check!(Either<u8, i8>, 2,
+           Left(132u8), "Left(132u8)",
+           Right(-32i8), "Right(-32i8)");
+    check!(Either<u8, i16>, 4,
+           Left(132u8), "Left(132u8)",
+           Right(-20000i16), "Right(-20000i16)");
+}
index 8d4680436a42311f7272a302bfacfbb4fe05b82f..5707406de146c4edf822bb23d7989fd84c3ce1fa 100644 (file)
@@ -25,6 +25,6 @@ pub fn main() {
         let _b = Foo;
     };
 
-    let s = x.unwrap_err().move::<SendStr>().unwrap();
+    let s = x.unwrap_err().move::<&'static str>().unwrap();
     assert_eq!(s.as_slice(), "This failure should happen.");
 }
diff --git a/src/test/run-pass/zero-size-type-destructors.rs b/src/test/run-pass/zero-size-type-destructors.rs
new file mode 100644 (file)
index 0000000..fd272a4
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2013 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.
+
+static mut destructions : int = 3;
+
+pub fn foo() {
+    #[unsafe_no_drop_flag]
+    struct Foo;
+
+    impl Drop for Foo {
+        fn drop(&mut self) {
+          unsafe { destructions -= 1 };
+        }
+    };
+
+    let _x = [Foo, Foo, Foo];
+}
+
+pub fn main() {
+  foo();
+  assert!((unsafe { destructions } == 0));
+}