]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #15025 : alexcrichton/rust/rollup, r=alexcrichton
authorbors <bors@rust-lang.org>
Thu, 19 Jun 2014 01:41:43 +0000 (01:41 +0000)
committerbors <bors@rust-lang.org>
Thu, 19 Jun 2014 01:41:43 +0000 (01:41 +0000)
88 files changed:
src/compiler-rt
src/compiletest/runtest.rs
src/doc/complement-cheatsheet.md
src/doc/rust.md
src/etc/2014-06-rewrite-bytes-macros.py [new file with mode: 0755]
src/etc/vim/autoload/rust.vim [new file with mode: 0644]
src/etc/vim/doc/rust.txt [new file with mode: 0644]
src/etc/vim/ftplugin/rust.vim
src/etc/vim/syntax/rust.vim
src/liballoc/heap.rs
src/libcollections/enum_set.rs
src/libcollections/hash/mod.rs
src/libcollections/slice.rs
src/libcollections/str.rs
src/libcore/mem.rs
src/libcore/num/int_macros.rs
src/libcore/num/mod.rs
src/libcore/num/uint_macros.rs
src/libdebug/repr.rs
src/libgreen/lib.rs
src/libnative/io/file_unix.rs
src/libnative/io/file_win32.rs
src/libnative/io/net.rs
src/libnative/lib.rs
src/libnative/task.rs
src/libnum/bigint.rs
src/librand/lib.rs
src/librustc/driver/mod.rs
src/librustc/metadata/filesearch.rs
src/librustc/middle/borrowck/move_data.rs
src/librustc/middle/liveness.rs
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/adt.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/expr.rs
src/librustdoc/html/layout.rs
src/librustdoc/html/render.rs
src/librustrt/args.rs
src/librustrt/c_str.rs
src/librustuv/net.rs
src/libserialize/base64.rs
src/libserialize/ebml.rs
src/libserialize/hex.rs
src/libstd/io/buffered.rs
src/libstd/io/fs.rs
src/libstd/io/mem.rs
src/libstd/io/mod.rs
src/libstd/io/pipe.rs
src/libstd/io/stdio.rs
src/libstd/num/mod.rs
src/libstd/path/mod.rs
src/libstd/path/posix.rs
src/libstd/path/windows.rs
src/libstd/task.rs
src/libsync/lock.rs
src/libsyntax/ext/bytes.rs
src/libterm/terminfo/parm.rs
src/libterm/terminfo/parser/compiled.rs
src/libtest/lib.rs
src/libuuid/lib.rs
src/snapshots.txt
src/test/bench/msgsend-pipes-shared.rs
src/test/bench/msgsend-pipes.rs
src/test/bench/shootout-pfib.rs
src/test/bench/sudoku.rs
src/test/compile-fail/borrowck-array-double-move.rs [new file with mode: 0644]
src/test/compile-fail/macros-nonfatal-errors.rs
src/test/compile-fail/syntax-extension-bytes-non-ascii-char-literal.rs
src/test/compile-fail/syntax-extension-bytes-non-literal.rs
src/test/compile-fail/syntax-extension-bytes-too-large-integer-literal.rs
src/test/compile-fail/syntax-extension-bytes-too-large-u8-literal.rs
src/test/compile-fail/syntax-extension-bytes-too-small-integer-literal.rs
src/test/compile-fail/syntax-extension-bytes-too-small-u8-literal.rs
src/test/compile-fail/syntax-extension-bytes-unsupported-literal.rs
src/test/debuginfo/issue14411.rs [new file with mode: 0644]
src/test/run-pass/issue-14865.rs [new file with mode: 0644]
src/test/run-pass/issue-14958.rs [new file with mode: 0644]
src/test/run-pass/issue-2190-1.rs
src/test/run-pass/issue-4333.rs
src/test/run-pass/task-comm-12.rs
src/test/run-pass/task-comm-3.rs
src/test/run-pass/task-comm-9.rs
src/test/run-pass/task-stderr.rs [new file with mode: 0644]
src/test/run-pass/tcp-stress.rs
src/test/run-pass/tempfile.rs
src/test/run-pass/trait-coercion.rs
src/test/run-pass/yield.rs
src/test/run-pass/yield1.rs

index 7b97b8468f0614072cf3299fa8c51e85f609316f..62a4ca6055ad6fda8faf767b93b5736dcdfb7013 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 7b97b8468f0614072cf3299fa8c51e85f609316f
+Subproject commit 62a4ca6055ad6fda8faf767b93b5736dcdfb7013
index 1e07068dd6f6294fdf14fd246cce9ea7db96f0c5..ce3c2d7de8095aab75c5ac3a78177508379a53b7 100644 (file)
@@ -1269,7 +1269,7 @@ fn make_out_name(config: &Config, testfile: &Path, extension: &str) -> Path {
 
 fn aux_output_dir_name(config: &Config, testfile: &Path) -> Path {
     let mut f = output_base_name(config, testfile);
-    match f.filename().map(|s| Vec::from_slice(s).append(bytes!(".libaux"))) {
+    match f.filename().map(|s| Vec::from_slice(s).append(b".libaux")) {
         Some(v) => f.set_filename(v),
         None => ()
     }
@@ -1490,7 +1490,7 @@ fn append_suffix_to_stem(p: &Path, suffix: &str) -> Path {
         (*p).clone()
     } else {
         let stem = p.filestem().unwrap();
-        p.with_filename(Vec::from_slice(stem).append(bytes!("-")).append(suffix.as_bytes()))
+        p.with_filename(Vec::from_slice(stem).append(b"-").append(suffix.as_bytes()))
     }
 }
 
index 9797284a65b7d6e58ad40700a438be000a030db3..84fd140a23af4b44fcc22be6fe0ec3aabb78c673 100644 (file)
@@ -76,7 +76,7 @@ character.
 ~~~
 use std::str;
 
-let x = bytes!(72u8,"ello ",0xF0,0x90,0x80,"World!");
+let x = b"Hello \xF0\x90\x80World!";
 let y = str::from_utf8_lossy(x);
 ~~~
 
index cc41b8edfbf8d888a63a32e0a249e2eda6d0ec32..7e5e5b2e67a43be2c92e2f6d9c78d02b38d3db32 100644 (file)
@@ -378,6 +378,19 @@ the characters `U+0022` (double-quote) (except when followed by at least as
 many `U+0023` (`#`) characters as were used to start the raw string literal) or
 `U+005C` (`\`) do not have any special meaning.
 
+Examples for byte string literals:
+
+~~~~
+b"foo"; br"foo";                     // foo
+b"\"foo\""; br#""foo""#;             // "foo"
+
+b"foo #\"# bar";
+br##"foo #"# bar"##;                 // foo #"# bar
+
+b"\x52"; b"R"; br"R";                // R
+b"\\x52"; br"\x52";                  // \x52
+~~~~
+
 #### Number literals
 
 ~~~~ {.ebnf .gram}
diff --git a/src/etc/2014-06-rewrite-bytes-macros.py b/src/etc/2014-06-rewrite-bytes-macros.py
new file mode 100755 (executable)
index 0000000..ceda4bf
--- /dev/null
@@ -0,0 +1,138 @@
+#!/bin/env python
+#
+# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+# file at the top-level directory of this distribution and at
+# http://rust-lang.org/COPYRIGHT.
+#
+# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+# option. This file may not be copied, modified, or distributed
+# except according to those terms.
+
+import sys
+import subprocess
+import re
+
+
+def main():
+    if len(sys.argv) <= 1:
+        print('Usage: %s [ --apply ] filename1.rs filename2.rs ...'
+              % sys.argv[0])
+    elif sys.argv[1] == '--apply':
+        for filename in sys.argv[2:]:
+            patch(filename)
+    else:
+        for filename in sys.argv[1:]:
+            diff(filename)
+
+
+def patch(filename):
+    source = read(filename)
+    rewritten = rewrite_bytes_macros(source)
+    if rewritten is not None and rewritten != source:
+        write(filename, rewritten)
+
+
+def diff(filename):
+    rewritten = rewrite_bytes_macros(read(filename))
+    if rewritten is not None:
+        p = subprocess.Popen(['diff', '-u', filename, '-'],
+                             stdin=subprocess.PIPE)
+        p.stdin.write(rewritten)
+        p.stdin.close()
+        p.wait()
+
+
+def read(filename):
+    with open(filename, 'rb') as f:
+        return f.read()
+
+
+def write(filename, content):
+    with open(filename, 'wb') as f:
+        f.write(content)
+
+
+def rewrite_bytes_macros(source):
+    rewritten, num_occurrences = BYTES_MACRO_RE.subn(rewrite_one_macro, source)
+    if num_occurrences > 0:
+        return rewritten
+
+
+BYTES_MACRO_RE = re.compile(br'bytes!\(  (?P<args>  [^)]*  )  \)', re.VERBOSE)
+
+
+def rewrite_one_macro(match):
+    try:
+        bytes = parse_bytes(split_args(match.group('args')))
+        return b'b"' + b''.join(map(escape, bytes)) + b'"'
+    except SkipThisRewrite:
+        print('Skipped: %s' % match.group(0).decode('utf8', 'replace'))
+        return match.group(0)
+
+
+class SkipThisRewrite(Exception):
+    pass
+
+
+def split_args(args):
+    previous = b''
+    for arg in args.split(b','):
+        if previous:
+            arg = previous + b',' + arg
+        if arg.count(b'"') % 2 == 0:
+            yield arg
+            previous = b''
+        else:
+            previous = arg
+    if previous:
+        yield previous
+
+
+def parse_bytes(args):
+    for arg in args:
+        arg = arg.strip()
+        if (arg.startswith(b'"') and arg.endswith(b'"')) or (
+                arg.startswith(b"'") and arg.endswith(b"'")):
+            # Escaped newline means something different in Rust and Python.
+            if b'\\\n' in arg:
+                raise SkipThisRewrite
+            for byte in eval(b'u' + arg).encode('utf8'):
+                yield ord(byte)
+        else:
+            if arg.endswith(b'u8'):
+                arg = arg[:-2]
+            # Assume that all Rust integer literals
+            # are valid Python integer literals
+            value = int(eval(arg))
+            assert value <= 0xFF
+            yield value
+
+
+def escape(byte):
+    c = chr(byte)
+    escaped = {
+        b'\0': br'\0',
+        b'\t': br'\t',
+        b'\n': br'\n',
+        b'\r': br'\r',
+        b'\'': b'\\\'',
+        b'\\': br'\\',
+    }.get(c)
+    if escaped is not None:
+        return escaped
+    elif b' ' <= c <= b'~':
+        return chr(byte)
+    else:
+        return ('\\x%02X' % byte).encode('ascii')
+
+
+if str is not bytes:
+    # Python 3.x
+    ord = lambda x: x
+    chr = lambda x: bytes([x])
+
+
+if __name__ == '__main__':
+    main()
diff --git a/src/etc/vim/autoload/rust.vim b/src/etc/vim/autoload/rust.vim
new file mode 100644 (file)
index 0000000..c6b9b31
--- /dev/null
@@ -0,0 +1,225 @@
+" Author: Kevin Ballard
+" Description: Helper functions for Rust commands/mappings
+" Last Modified: May 27, 2014
+
+" Jump {{{1
+
+function! rust#Jump(mode, function) range
+       let cnt = v:count1
+       normal! m'
+       if a:mode ==# 'v'
+               norm! gv
+       endif
+       let foldenable = &foldenable
+       set nofoldenable
+       while cnt > 0
+               execute "call <SID>Jump_" . a:function . "()"
+               let cnt = cnt - 1
+       endwhile
+       let &foldenable = foldenable
+endfunction
+
+function! s:Jump_Back()
+       call search('{', 'b')
+       keepjumps normal! w99[{
+endfunction
+
+function! s:Jump_Forward()
+       normal! j0
+       call search('{', 'b')
+       keepjumps normal! w99[{%
+       call search('{')
+endfunction
+
+" Run {{{1
+
+function! rust#Run(bang, args)
+       if a:bang
+               let idx = index(a:args, '--')
+               if idx != -1
+                       let rustc_args = idx == 0 ? [] : a:args[:idx-1]
+                       let args = a:args[idx+1:]
+               else
+                       let rustc_args = a:args
+                       let args = []
+               endif
+       else
+               let rustc_args = []
+               let args = a:args
+       endif
+
+       let b:rust_last_rustc_args = rustc_args
+       let b:rust_last_args = args
+
+       call s:WithPath(function("s:Run"), rustc_args, args)
+endfunction
+
+function! s:Run(path, rustc_args, args)
+       try
+               let exepath = tempname()
+               if has('win32')
+                       let exepath .= '.exe'
+               endif
+
+               let rustc_args = [a:path, '-o', exepath] + a:rustc_args
+
+               let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
+
+               let output = system(shellescape(rustc) . " " . join(map(rustc_args, 'shellescape(v:val)')))
+               if output != ''
+                       echohl WarningMsg
+                       echo output
+                       echohl None
+               endif
+               if !v:shell_error
+                       exe '!' . shellescape(exepath) . " " . join(map(a:args, 'shellescape(v:val)'))
+               endif
+       finally
+               if exists("exepath")
+                       silent! call delete(exepath)
+               endif
+       endtry
+endfunction
+
+" Expand {{{1
+
+function! rust#Expand(bang, args)
+       if a:bang && !empty(a:args)
+               let pretty = a:args[0]
+               let args = a:args[1:]
+       else
+               let pretty = "expanded"
+               let args = a:args
+       endif
+       call s:WithPath(function("s:Expand"), pretty, args)
+endfunction
+
+function! s:Expand(path, pretty, args)
+       try
+               let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
+
+               let args = [a:path, '--pretty', a:pretty] + a:args
+               let output = system(shellescape(rustc) . " " . join(map(args, "shellescape(v:val)")))
+               if v:shell_error
+                       echohl WarningMsg
+                       echo output
+                       echohl None
+               else
+                       new
+                       silent put =output
+                       1
+                       d
+                       setl filetype=rust
+                       setl buftype=nofile
+                       setl bufhidden=hide
+                       setl noswapfile
+               endif
+       endtry
+endfunction
+
+function! rust#CompleteExpand(lead, line, pos)
+       if a:line[: a:pos-1] =~ '^RustExpand!\s*\S*$'
+               " first argument and it has a !
+               let list = ["normal", "expanded", "typed", "expanded,identified", "flowgraph="]
+               if !empty(a:lead)
+                       call filter(list, "v:val[:len(a:lead)-1] == a:lead")
+               endif
+               return list
+       endif
+
+       return glob(escape(a:lead, "*?[") . '*', 0, 1)
+endfunction
+
+" Emit {{{1
+
+function! rust#Emit(type, args)
+       call s:WithPath(function("s:Emit"), a:type, a:args)
+endfunction
+
+function! s:Emit(path, type, args)
+       try
+               let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
+
+               let args = [a:path, '--emit', a:type, '-o', '-'] + a:args
+               let output = system(shellescape(rustc) . " " . join(map(args, "shellescape(v:val)")))
+               if v:shell_error
+                       echohl WarningMsg
+                       echo output
+                       echohl None
+               else
+                       new
+                       silent put =output
+                       1
+                       d
+                       if a:type == "ir"
+                               setl filetype=llvm
+                       elseif a:type == "asm"
+                               setl filetype=asm
+                       endif
+                       setl buftype=nofile
+                       setl bufhidden=hide
+                       setl noswapfile
+               endif
+       endtry
+endfunction
+
+" Utility functions {{{1
+
+function! s:WithPath(func, ...)
+       try
+               let save_write = &write
+               set write
+               let path = expand('%')
+               let pathisempty = empty(path)
+               if pathisempty || !save_write
+                       " use a temporary file named 'unnamed.rs' inside a temporary
+                       " directory. This produces better error messages
+                       let tmpdir = tempname()
+                       call mkdir(tmpdir)
+
+                       let save_cwd = getcwd()
+                       silent exe 'lcd' tmpdir
+
+                       let path = 'unnamed.rs'
+
+                       let save_mod = &mod
+                       set nomod
+
+                       silent exe 'keepalt write! ' . path
+                       if pathisempty
+                               silent keepalt 0file
+                       endif
+               else
+                       update
+               endif
+
+               call call(a:func, [path] + a:000)
+       finally
+               if exists("save_mod")   | let &mod = save_mod          | endif
+               if exists("save_write") | let &write = save_write      | endif
+               if exists("save_cwd")   | silent exe 'lcd' save_cwd    | endif
+               if exists("tmpdir")     | silent call s:RmDir(tmpdir)  | endif
+       endtry
+endfunction
+
+function! rust#AppendCmdLine(text)
+       call setcmdpos(getcmdpos())
+       let cmd = getcmdline() . a:text
+       return cmd
+endfunction
+
+function! s:RmDir(path)
+       " sanity check; make sure it's not empty, /, or $HOME
+       if empty(a:path)
+               echoerr 'Attempted to delete empty path'
+               return 0
+       elseif a:path == '/' || a:path == $HOME
+               echoerr 'Attempted to delete protected path: ' . a:path
+               return 0
+       endif
+       silent exe "!rm -rf " . shellescape(a:path)
+endfunction
+
+" }}}1
+
+" vim: set noet sw=4 ts=4:
diff --git a/src/etc/vim/doc/rust.txt b/src/etc/vim/doc/rust.txt
new file mode 100644 (file)
index 0000000..96ed69d
--- /dev/null
@@ -0,0 +1,150 @@
+*rust.txt*      Filetype plugin for Rust
+
+==============================================================================
+CONTENTS                                                                *rust*
+
+1. Introduction                                                   |rust-intro|
+2. Settings                                                    |rust-settings|
+3. Commands                                                    |rust-commands|
+4. Mappings                                                    |rust-mappings|
+
+==============================================================================
+INTRODUCTION                                                      *rust-intro*
+
+This plugin provides syntax and supporting functionality for the Rust
+filetype.
+
+==============================================================================
+SETTINGS                                                       *rust-settings*
+
+This plugin has a few variables you can define in your vimrc that change the
+behavior of the plugin.
+
+                                                                *g:rustc_path*
+g:rustc_path~
+       Set this option to the path to rustc for use in the |:RustRun| and
+       |:RustExpand| commands. If unset, "rustc" will be located in $PATH: >
+           let g:rustc_path = $HOME."/bin/rustc"
+<
+
+                                                  *g:rustc_makeprg_no_percent*
+g:rustc_makeprg_no_percent~
+       Set this option to 1 to have 'makeprg' default to "rustc" instead of
+       "rustc %": >
+           let g:rustc_makeprg_no_percent = 1
+<
+
+                                                              *g:rust_conceal*
+g:rust_conceal~
+       Set this option to turn on the basic |conceal| support: >
+           let g:rust_conceal = 1
+<
+
+                                                     *g:rust_conceal_mod_path*
+g:rust_conceal_mod_path~
+       Set this option to turn on |conceal| for the path connecting token
+       "::": >
+           let g:rust_conceal_mod_path = 1
+<
+
+                                                          *g:rust_conceal_pub*
+g:rust_conceal_pub~
+       Set this option to turn on |conceal| for the "pub" token: >
+           let g:rust_conceal_pub = 1
+<
+
+                                                  *g:rust_bang_comment_leader*
+g:rust_bang_comment_leader~
+       Set this option to 1 to preserve the leader on multi-line doc comments
+       using the /*! syntax: >
+           let g:rust_bang_comment_leader = 1
+<
+
+                                                 *g:ftplugin_rust_source_path*
+g:ftplugin_rust_source_path~
+       Set this option to a path that should be prepended to 'path' for Rust
+       source files: >
+           let g:ftplugin_rust_source_path = $HOME.'/dev/rust'
+<
+
+==============================================================================
+COMMANDS                                                       *rust-commands*
+
+:RustRun  [args]                                                    *:RustRun*
+:RustRun! [rustc-args] [--] [args]
+               Compiles and runs the current file. If it has unsaved changes,
+               it will be saved first using |:update|. If the current file is
+               an unnamed buffer, it will be written to a temporary file
+               first. The compiled binary is always placed in a temporary
+               directory, but is run from the current directory.
+
+               The arguments given to |:RustRun| will be passed to the
+               compiled binary.
+
+               If ! is specified, the arguments are passed to rustc instead.
+               A "--" argument will separate the rustc arguments from the
+               arguments passed to the binary.
+
+               If |g:rustc_path| is defined, it is used as the path to rustc.
+               Otherwise it is assumed rustc can be found in $PATH.
+
+:RustExpand  [args]                                              *:RustExpand*
+:RustExpand! [TYPE] [args]
+               Expands the current file using --pretty and displays the
+               results in a new split. If the current file has unsaved
+               changes, it will be saved first using |:update|. If the
+               current file is an unnamed buffer, it will be written to a
+               temporary file first.
+
+               The arguments given to |:RustExpand| will be passed to rustc.
+               This is largely intended for specifying various --cfg
+               configurations.
+
+               If ! is specified, the first argument is the expansion type to
+               pass to rustc --pretty. Otherwise it will default to
+               "expanded".
+
+               If |g:rustc_path| is defined, it is used as the path to rustc.
+               Otherwise it is assumed rustc can be found in $PATH.
+
+:RustEmitIr [args]                                               *:RustEmitIr*
+               Compiles the current file to LLVM IR and displays the results
+               in a new split. If the current file has unsaved changes, it
+               will be saved first using |:update|. If the current file is an
+               unnamed buffer, it will be written to a temporary file first.
+
+               The arguments given to |:RustEmitIr| will be passed to rustc.
+
+               If |g:rustc_path| is defined, it is used as the path to rustc.
+               Otherwise it is assumed rustc can be found in $PATH.
+
+:RustEmitAsm [args]                                             *:RustEmitAsm*
+               Compiles the current file to assembly and displays the results
+               in a new split. If the current file has unsaved changes, it
+               will be saved first using |:update|. If the current file is an
+               unnamed buffer, it will be written to a temporary file first.
+
+               The arguments given to |:RustEmitAsm| will be passed to rustc.
+
+               If |g:rustc_path| is defined, it is used as the path to rustc.
+               Otherwise it is assumed rustc can be found in $PATH.
+
+==============================================================================
+MAPPINGS                                                       *rust-mappings*
+
+This plugin defines mappings for |[[| and |]]| to support hanging indents.
+
+It also has a few other mappings:
+
+                                                       *rust_<D-r>*
+<D-r>                  Executes |:RustRun| with no arguments.
+                       Note: This binding is only available in MacVim.
+
+                                                       *rust_<D-R>*
+<D-R>                  Populates the command line with |:RustRun|! using the
+                       arguments given to the last invocation, but does not
+                       execute it.
+                       Note: This binding is only available in MacVim.
+
+==============================================================================
+ vim:tw=78:sw=4:noet:ts=8:ft=help:norl:
index b70cda9b998c405ff372d89825f28f847e8b4384..65f9f4105ad8fda5c8d58657f5832072102e47d5 100644 (file)
@@ -1,13 +1,19 @@
-" Vim syntax file
 " Language:     Rust
+" Description:  Vim syntax file for Rust
 " Maintainer:   Chris Morgan <me@chrismorgan.info>
-" Last Change:  2014 Feb 27
+" Maintainer:   Kevin Ballard <kevin@sb.org>
+" Last Change:  May 27, 2014
 
 if exists("b:did_ftplugin")
        finish
 endif
 let b:did_ftplugin = 1
 
+let s:save_cpo = &cpo
+set cpo&vim
+
+" Variables {{{1
+
 " The rust source code at present seems to typically omit a leader on /*!
 " comments, so we'll use that as our default, but make it easy to switch.
 " This does not affect indentation at all (I tested it with and without
@@ -42,22 +48,59 @@ if exists("g:loaded_delimitMate")
        let b:delimitMate_excluded_regions = delimitMate#Get("excluded_regions") . ',rustLifetimeCandidate,rustGenericLifetimeCandidate'
 endif
 
+" Motion Commands {{{1
+
 " Bind motion commands to support hanging indents
-nnoremap <silent> <buffer> [[ :call <SID>Rust_Jump('n', 'Back')<CR>
-nnoremap <silent> <buffer> ]] :call <SID>Rust_Jump('n', 'Forward')<CR>
-xnoremap <silent> <buffer> [[ :call <SID>Rust_Jump('v', 'Back')<CR>
-xnoremap <silent> <buffer> ]] :call <SID>Rust_Jump('v', 'Forward')<CR>
-onoremap <silent> <buffer> [[ :call <SID>Rust_Jump('o', 'Back')<CR>
-onoremap <silent> <buffer> ]] :call <SID>Rust_Jump('o', 'Forward')<CR>
+nnoremap <silent> <buffer> [[ :call rust#Jump('n', 'Back')<CR>
+nnoremap <silent> <buffer> ]] :call rust#Jump('n', 'Forward')<CR>
+xnoremap <silent> <buffer> [[ :call rust#Jump('v', 'Back')<CR>
+xnoremap <silent> <buffer> ]] :call rust#Jump('v', 'Forward')<CR>
+onoremap <silent> <buffer> [[ :call rust#Jump('o', 'Back')<CR>
+onoremap <silent> <buffer> ]] :call rust#Jump('o', 'Forward')<CR>
+
+" Commands {{{1
+
+" See |:RustRun| for docs
+command! -nargs=* -complete=file -bang -bar -buffer RustRun call rust#Run(<bang>0, [<f-args>])
+
+" See |:RustExpand| for docs
+command! -nargs=* -complete=customlist,rust#CompleteExpand -bang -bar -buffer RustExpand call rust#Expand(<bang>0, [<f-args>])
+
+" See |:RustEmitIr| for docs
+command! -nargs=* -bar -buffer RustEmitIr call rust#Emit("ir", [<f-args>])
+
+" See |:RustEmitAsm| for docs
+command! -nargs=* -bar -buffer RustEmitAsm call rust#Emit("asm", [<f-args>])
+
+" Mappings {{{1
+
+" Bind ⌘R in MacVim to :RustRun
+nnoremap <silent> <buffer> <D-r> :RustRun<CR>
+" Bind ⌘⇧R in MacVim to :RustRun! pre-filled with the last args
+nnoremap <buffer> <D-R> :RustRun! <C-r>=join(b:rust_last_rustc_args)<CR><C-\>erust#AppendCmdLine(' -- ' . join(b:rust_last_args))<CR>
+
+if !exists("b:rust_last_rustc_args") || !exists("b:rust_last_args")
+       let b:rust_last_rustc_args = []
+       let b:rust_last_args = []
+endif
+
+" Cleanup {{{1
 
 let b:undo_ftplugin = "
                \setlocal formatoptions< comments< commentstring< includeexpr< suffixesadd<
                \|if exists('b:rust_original_delimitMate_excluded_regions')
                  \|let b:delimitMate_excluded_regions = b:rust_original_delimitMate_excluded_regions
                  \|unlet b:rust_original_delimitMate_excluded_regions
-               \|elseif exists('b:delimitMate_excluded_regions')
-                 \|unlet b:delimitMate_excluded_regions
+               \|else
+                 \|unlet! b:delimitMate_excluded_regions
                \|endif
+               \|unlet! b:rust_last_rustc_args b:rust_last_args
+               \|delcommand RustRun
+               \|delcommand RustExpand
+               \|delcommand RustEmitIr
+               \|delcommand RustEmitAsm
+               \|nunmap <buffer> <D-r>
+               \|nunmap <buffer> <D-R>
                \|nunmap <buffer> [[
                \|nunmap <buffer> ]]
                \|xunmap <buffer> [[
@@ -66,31 +109,9 @@ let b:undo_ftplugin = "
                \|ounmap <buffer> ]]
                \"
 
-if exists('*<SID>Rust_Jump') | finish | endif
+" }}}1
 
-function! <SID>Rust_Jump(mode, function) range
-       let cnt = v:count1
-       normal! m'
-       if a:mode ==# 'v'
-               norm! gv
-       endif
-       let foldenable = &foldenable
-       set nofoldenable
-       while cnt > 0
-               execute "call <SID>Rust_Jump_" . a:function . "()"
-               let cnt = cnt - 1
-       endwhile
-       let &foldenable = foldenable
-endfunction
-
-function! <SID>Rust_Jump_Back()
-       call search('{', 'b')
-       keepjumps normal! w99[{
-endfunction
-
-function! <SID>Rust_Jump_Forward()
-       normal! j0
-       call search('{', 'b')
-       keepjumps normal! w99[{%
-       call search('{')
-endfunction
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: set noet sw=4 ts=4:
index 77348335eb3464094ff1e49af9ccdb496f58e307..a0488cdb05ab47c42f02f59e379370db671441f2 100644 (file)
@@ -145,11 +145,13 @@ syn match     rustOperator     display "&&\|||"
 syn match     rustMacro       '\w\(\w\)*!' contains=rustAssert,rustFail
 syn match     rustMacro       '#\w\(\w\)*' contains=rustAssert,rustFail
 
-syn match     rustSpecialError display contained /\\./
-syn match     rustSpecial     display contained /\\\([nrt0\\'"]\|x\x\{2}\|u\x\{4}\|U\x\{8}\)/
+syn match     rustEscapeError   display contained /\\./
+syn match     rustEscape        display contained /\\\([nrt0\\'"]\|x\x\{2}\)/
+syn match     rustEscapeUnicode display contained /\\\(u\x\{4}\|U\x\{8}\)/
 syn match     rustStringContinuation display contained /\\\n\s*/
-syn region    rustString      start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=rustSpecial,rustSpecialError,rustStringContinuation,@Spell
-syn region    rustString      start='r\z(#*\)"' end='"\z1' contains=@Spell
+syn region    rustString      start=+b"+ skip=+\\\\\|\\"+ end=+"+ contains=rustEscape,rustEscapeError,rustStringContinuation
+syn region    rustString      start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=rustEscape,rustEscapeUnicode,rustEscapeError,rustStringContinuation,@Spell
+syn region    rustString      start='b\?r\z(#*\)"' end='"\z1' contains=@Spell
 
 syn region    rustAttribute   start="#!\?\[" end="\]" contains=rustString,rustDeriving
 syn region    rustDeriving    start="deriving(" end=")" contained contains=rustTrait
@@ -177,7 +179,11 @@ syn region rustGenericLifetimeCandidate display start=/\%(<\|,\s*\)\@<='/ end=/[
 
 "rustLifetime must appear before rustCharacter, or chars will get the lifetime highlighting
 syn match     rustLifetime    display "\'\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*"
-syn match   rustCharacter   /'\([^'\\]\|\\\(.\|x\x\{2}\|u\x\{4}\|U\x\{8}\)\)'/ contains=rustSpecial,rustSpecialError
+syn match   rustCharacterInvalid   display contained /b\?'\zs[\n\r\t']\ze'/
+" The groups negated here add up to 0-255 but nothing else (they do not seem to go beyond ASCII).
+syn match   rustCharacterInvalidUnicode   display contained /b'\zs[^[:cntrl:][:graph:][:alnum:][:space:]]\ze'/
+syn match   rustCharacter   /b'\([^\\]\|\\\(.\|x\x\{2}\)\)'/ contains=rustEscape,rustEscapeError,rustCharacterInvalid,rustCharacterInvalidUnicode
+syn match   rustCharacter   /'\([^\\]\|\\\(.\|x\x\{2}\|u\x\{4}\|U\x\{8}\)\)'/ contains=rustEscape,rustEscapeUnicode,rustEscapeError,rustCharacterInvalid
 
 syn region rustCommentLine                                        start="//"                      end="$"   contains=rustTodo,@Spell
 syn region rustCommentLineDoc                                     start="//\%(//\@!\|!\)"         end="$"   contains=rustTodo,@Spell
@@ -215,10 +221,13 @@ hi def link rustIdentifierPrime rustIdentifier
 hi def link rustTrait           rustType
 
 hi def link rustSigil         StorageClass
-hi def link rustSpecial       Special
-hi def link rustSpecialError  Error
+hi def link rustEscape        Special
+hi def link rustEscapeUnicode rustEscape
+hi def link rustEscapeError   Error
 hi def link rustStringContinuation Special
 hi def link rustString        String
+hi def link rustCharacterInvalid Error
+hi def link rustCharacterInvalidUnicode rustCharacterInvalid
 hi def link rustCharacter     Character
 hi def link rustNumber        Number
 hi def link rustBoolean       Boolean
index 79a616b9555aa1a80c8688c424ab29ea3ccb6226..b4d0057778a1a395255300163a03192be6a6c743 100644 (file)
@@ -132,7 +132,7 @@ unsafe fn closure_exchange_malloc(drop_glue: fn(*mut u8), size: uint,
 mod imp {
     use core::option::{None, Option};
     use core::ptr::{RawPtr, mut_null, null};
-    use core::num::Bitwise;
+    use core::num::Int;
     use libc::{c_char, c_int, c_void, size_t};
 
     #[link(name = "jemalloc", kind = "static")]
index 34514fde9dbd1456c8e55465a3860d2c5de7ac11..1360b412c23704dfdbeebecc7240dd1caeace739 100644 (file)
@@ -15,8 +15,6 @@
 
 use core::prelude::*;
 
-use core::num::Bitwise;
-
 #[deriving(Clone, PartialEq, Eq, Hash, Show)]
 /// A specialized Set implementation to use enum types.
 pub struct EnumSet<E> {
index bd7bab456ba012cb962336c9498d895459d7ccf9..a0c0c9f97357816edc7470a674a78e1fb82ba6fb 100644 (file)
@@ -98,46 +98,30 @@ pub trait Writer {
 
 //////////////////////////////////////////////////////////////////////////////
 
-fn id<T>(t: T) -> T { t }
-
-macro_rules! impl_hash(
-    ( $($ty:ident, $uty:ident, $f:path;)* ) => (
-        $(
-            impl<S: Writer> Hash<S> for $ty {
-                #[inline]
-                fn hash(&self, state: &mut S) {
-                    let a: [u8, ..::core::$ty::BYTES] = unsafe {
-                        mem::transmute($f(*self as $uty) as $ty)
-                    };
-                    state.write(a.as_slice())
-                }
+macro_rules! impl_hash {
+    ($ty:ident, $uty:ident) => {
+        impl<S: Writer> Hash<S> for $ty {
+            #[inline]
+            fn hash(&self, state: &mut S) {
+                let a: [u8, ..::core::$ty::BYTES] = unsafe {
+                    mem::transmute((*self as $uty).to_le() as $ty)
+                };
+                state.write(a.as_slice())
             }
-        )*
-    )
-)
-
-impl_hash!(
-    u8, u8, id;
-    u16, u16, mem::to_le16;
-    u32, u32, mem::to_le32;
-    u64, u64, mem::to_le64;
-    i8, u8, id;
-    i16, u16, mem::to_le16;
-    i32, u32, mem::to_le32;
-    i64, u64, mem::to_le64;
-)
-
-#[cfg(target_word_size = "32")]
-impl_hash!(
-    uint, u32, mem::to_le32;
-    int, u32, mem::to_le32;
-)
+        }
+    }
+}
 
-#[cfg(target_word_size = "64")]
-impl_hash!(
-    uint, u64, mem::to_le64;
-    int, u64, mem::to_le64;
-)
+impl_hash!(u8, u8)
+impl_hash!(u16, u16)
+impl_hash!(u32, u32)
+impl_hash!(u64, u64)
+impl_hash!(uint, uint)
+impl_hash!(i8, u8)
+impl_hash!(i16, u16)
+impl_hash!(i32, u32)
+impl_hash!(i64, u64)
+impl_hash!(int, uint)
 
 impl<S: Writer> Hash<S> for bool {
     #[inline]
index ff00ca58e8c7668b014105a3c0eaeb388bf37c36..f9826fcd2287ff8e37d39bc2a86a7c93b043a9ff 100644 (file)
@@ -1957,30 +1957,30 @@ fn test_shrink_to_fit() {
 
     #[test]
     fn test_starts_with() {
-        assert!(bytes!("foobar").starts_with(bytes!("foo")));
-        assert!(!bytes!("foobar").starts_with(bytes!("oob")));
-        assert!(!bytes!("foobar").starts_with(bytes!("bar")));
-        assert!(!bytes!("foo").starts_with(bytes!("foobar")));
-        assert!(!bytes!("bar").starts_with(bytes!("foobar")));
-        assert!(bytes!("foobar").starts_with(bytes!("foobar")));
+        assert!(b"foobar".starts_with(b"foo"));
+        assert!(!b"foobar".starts_with(b"oob"));
+        assert!(!b"foobar".starts_with(b"bar"));
+        assert!(!b"foo".starts_with(b"foobar"));
+        assert!(!b"bar".starts_with(b"foobar"));
+        assert!(b"foobar".starts_with(b"foobar"));
         let empty: &[u8] = [];
         assert!(empty.starts_with(empty));
-        assert!(!empty.starts_with(bytes!("foo")));
-        assert!(bytes!("foobar").starts_with(empty));
+        assert!(!empty.starts_with(b"foo"));
+        assert!(b"foobar".starts_with(empty));
     }
 
     #[test]
     fn test_ends_with() {
-        assert!(bytes!("foobar").ends_with(bytes!("bar")));
-        assert!(!bytes!("foobar").ends_with(bytes!("oba")));
-        assert!(!bytes!("foobar").ends_with(bytes!("foo")));
-        assert!(!bytes!("foo").ends_with(bytes!("foobar")));
-        assert!(!bytes!("bar").ends_with(bytes!("foobar")));
-        assert!(bytes!("foobar").ends_with(bytes!("foobar")));
+        assert!(b"foobar".ends_with(b"bar"));
+        assert!(!b"foobar".ends_with(b"oba"));
+        assert!(!b"foobar".ends_with(b"foo"));
+        assert!(!b"foo".ends_with(b"foobar"));
+        assert!(!b"bar".ends_with(b"foobar"));
+        assert!(b"foobar".ends_with(b"foobar"));
         let empty: &[u8] = [];
         assert!(empty.ends_with(empty));
-        assert!(!empty.ends_with(bytes!("foo")));
-        assert!(bytes!("foobar").ends_with(empty));
+        assert!(!empty.ends_with(b"foo"));
+        assert!(b"foobar".ends_with(empty));
     }
 
     #[test]
index 83601be83dec0f194ae923a26edcd6aa54d968b0..642e7cfc9a36f44be39d5e27ca1177583f6d1df1 100644 (file)
@@ -382,7 +382,7 @@ macro_rules! utf8_acc_cont_byte(
 /// # Example
 ///
 /// ```rust
-/// let input = bytes!("Hello ", 0xF0, 0x90, 0x80, "World");
+/// let input = b"Hello \xF0\x90\x80World";
 /// let output = std::str::from_utf8_lossy(input);
 /// assert_eq!(output.as_slice(), "Hello \uFFFDWorld");
 /// ```
@@ -391,7 +391,7 @@ pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> MaybeOwned<'a> {
         return Slice(unsafe { mem::transmute(v) })
     }
 
-    static REPLACEMENT: &'static [u8] = bytes!(0xEF, 0xBF, 0xBD); // U+FFFD in UTF-8
+    static REPLACEMENT: &'static [u8] = b"\xEF\xBF\xBD"; // U+FFFD in UTF-8
     let mut i = 0;
     let total = v.len();
     fn unsafe_get(xs: &[u8], i: uint) -> u8 {
@@ -994,7 +994,7 @@ fn test_collect() {
     fn test_into_bytes() {
         let data = "asdf".to_string();
         let buf = data.into_bytes();
-        assert_eq!(bytes!("asdf"), buf.as_slice());
+        assert_eq!(b"asdf", buf.as_slice());
     }
 
     #[test]
@@ -2050,58 +2050,58 @@ fn sum_len<S: Collection>(v: &[S]) -> uint {
 
     #[test]
     fn test_str_from_utf8() {
-        let xs = bytes!("hello");
+        let xs = b"hello";
         assert_eq!(from_utf8(xs), Some("hello"));
 
-        let xs = bytes!("ศไทย中华Việt Nam");
+        let xs = "ศไทย中华Việt Nam".as_bytes();
         assert_eq!(from_utf8(xs), Some("ศไทย中华Việt Nam"));
 
-        let xs = bytes!("hello", 0xff);
+        let xs = b"hello\xFF";
         assert_eq!(from_utf8(xs), None);
     }
 
     #[test]
     fn test_str_from_utf8_owned() {
-        let xs = Vec::from_slice(bytes!("hello"));
+        let xs = Vec::from_slice(b"hello");
         assert_eq!(from_utf8_owned(xs), Ok("hello".to_string()));
 
-        let xs = Vec::from_slice(bytes!("ศไทย中华Việt Nam"));
+        let xs = Vec::from_slice("ศไทย中华Việt Nam".as_bytes());
         assert_eq!(from_utf8_owned(xs), Ok("ศไทย中华Việt Nam".to_string()));
 
-        let xs = Vec::from_slice(bytes!("hello", 0xff));
+        let xs = Vec::from_slice(b"hello\xFF");
         assert_eq!(from_utf8_owned(xs),
-                   Err(Vec::from_slice(bytes!("hello", 0xff))));
+                   Err(Vec::from_slice(b"hello\xFF")));
     }
 
     #[test]
     fn test_str_from_utf8_lossy() {
-        let xs = bytes!("hello");
+        let xs = b"hello";
         assert_eq!(from_utf8_lossy(xs), Slice("hello"));
 
-        let xs = bytes!("ศไทย中华Việt Nam");
+        let xs = "ศไทย中华Việt Nam".as_bytes();
         assert_eq!(from_utf8_lossy(xs), Slice("ศไทย中华Việt Nam"));
 
-        let xs = bytes!("Hello", 0xC2, " There", 0xFF, " Goodbye");
+        let xs = b"Hello\xC2 There\xFF Goodbye";
         assert_eq!(from_utf8_lossy(xs), Owned("Hello\uFFFD There\uFFFD Goodbye".to_string()));
 
-        let xs = bytes!("Hello", 0xC0, 0x80, " There", 0xE6, 0x83, " Goodbye");
+        let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
         assert_eq!(from_utf8_lossy(xs), Owned("Hello\uFFFD\uFFFD There\uFFFD Goodbye".to_string()));
 
-        let xs = bytes!(0xF5, "foo", 0xF5, 0x80, "bar");
+        let xs = b"\xF5foo\xF5\x80bar";
         assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFD\uFFFDbar".to_string()));
 
-        let xs = bytes!(0xF1, "foo", 0xF1, 0x80, "bar", 0xF1, 0x80, 0x80, "baz");
+        let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
         assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFDbar\uFFFDbaz".to_string()));
 
-        let xs = bytes!(0xF4, "foo", 0xF4, 0x80, "bar", 0xF4, 0xBF, "baz");
+        let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
         assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFDbar\uFFFD\uFFFDbaz".to_string()));
 
-        let xs = bytes!(0xF0, 0x80, 0x80, 0x80, "foo", 0xF0, 0x90, 0x80, 0x80, "bar");
+        let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
         assert_eq!(from_utf8_lossy(xs), Owned("\uFFFD\uFFFD\uFFFD\uFFFD\
                                                foo\U00010000bar".to_string()));
 
         // surrogates
-        let xs = bytes!(0xED, 0xA0, 0x80, "foo", 0xED, 0xBF, 0xBF, "bar");
+        let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
         assert_eq!(from_utf8_lossy(xs), Owned("\uFFFD\uFFFD\uFFFDfoo\
                                                \uFFFD\uFFFD\uFFFDbar".to_string()));
     }
@@ -2298,8 +2298,8 @@ fn split_slice(b: &mut Bencher) {
     #[bench]
     fn is_utf8_100_ascii(b: &mut Bencher) {
 
-        let s = bytes!("Hello there, the quick brown fox jumped over the lazy dog! \
-                        Lorem ipsum dolor sit amet, consectetur. ");
+        let s = b"Hello there, the quick brown fox jumped over the lazy dog! \
+                  Lorem ipsum dolor sit amet, consectetur. ";
 
         assert_eq!(100, s.len());
         b.iter(|| {
@@ -2309,7 +2309,7 @@ fn is_utf8_100_ascii(b: &mut Bencher) {
 
     #[bench]
     fn is_utf8_100_multibyte(b: &mut Bencher) {
-        let s = bytes!("𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰");
+        let s = "𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰".as_bytes();
         assert_eq!(100, s.len());
         b.iter(|| {
             is_utf8(s)
@@ -2318,8 +2318,8 @@ fn is_utf8_100_multibyte(b: &mut Bencher) {
 
     #[bench]
     fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
-        let s = bytes!("Hello there, the quick brown fox jumped over the lazy dog! \
-                        Lorem ipsum dolor sit amet, consectetur. ");
+        let s = b"Hello there, the quick brown fox jumped over the lazy dog! \
+                  Lorem ipsum dolor sit amet, consectetur. ";
 
         assert_eq!(100, s.len());
         b.iter(|| {
@@ -2329,7 +2329,7 @@ fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
 
     #[bench]
     fn from_utf8_lossy_100_multibyte(b: &mut Bencher) {
-        let s = bytes!("𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰");
+        let s = "𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰".as_bytes();
         assert_eq!(100, s.len());
         b.iter(|| {
             let _ = from_utf8_lossy(s);
@@ -2338,7 +2338,7 @@ fn from_utf8_lossy_100_multibyte(b: &mut Bencher) {
 
     #[bench]
     fn from_utf8_lossy_invalid(b: &mut Bencher) {
-        let s = bytes!("Hello", 0xC0, 0x80, " There", 0xE6, 0x83, " Goodbye");
+        let s = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
         b.iter(|| {
             let _ = from_utf8_lossy(s);
         });
index 237efcd0096d0e190e7490d4cf64db62d5ff5ac0..5280ac0d64fb22c10eec5f9bd6ebae6235e90a9f 100644 (file)
@@ -13,9 +13,9 @@
 //! This module contains functions for querying the size and alignment of
 //! types, initializing and manipulating memory.
 
-use ptr;
 use intrinsics;
-use intrinsics::{bswap16, bswap32, bswap64};
+use num::Int;
+use ptr;
 
 pub use intrinsics::transmute;
 
@@ -172,153 +172,89 @@ pub unsafe fn move_val_init<T>(dst: &mut T, src: T) {
 /// Convert an u16 to little endian from the target's endianness.
 ///
 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] pub fn to_le16(x: u16) -> u16 { x }
-
-/// Convert an u16 to little endian from the target's endianness.
-///
-/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "big")] #[inline] #[stable]
-pub fn to_le16(x: u16) -> u16 { unsafe { bswap16(x) } }
-
-/// Convert an u32 to little endian from the target's endianness.
-///
-/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] #[stable]
-pub fn to_le32(x: u32) -> u32 { x }
+#[inline]
+#[deprecated = "use `Int::to_le` instead"]
+pub fn to_le16(x: u16) -> u16 { x.to_le() }
 
 /// Convert an u32 to little endian from the target's endianness.
 ///
 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "big")] #[inline] #[stable]
-pub fn to_le32(x: u32) -> u32 { unsafe { bswap32(x) } }
-
-/// Convert an u64 to little endian from the target's endianness.
-///
-/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] #[stable]
-pub fn to_le64(x: u64) -> u64 { x }
+#[inline]
+#[deprecated = "use `Int::to_le` instead"]
+pub fn to_le32(x: u32) -> u32 { x.to_le() }
 
 /// Convert an u64 to little endian from the target's endianness.
 ///
 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "big")] #[inline] #[stable]
-pub fn to_le64(x: u64) -> u64 { unsafe { bswap64(x) } }
-
-
-/// Convert an u16 to big endian from the target's endianness.
-///
-/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] #[stable]
-pub fn to_be16(x: u16) -> u16 { unsafe { bswap16(x) } }
+#[inline]
+#[deprecated = "use `Int::to_le` instead"]
+pub fn to_le64(x: u64) -> u64 { x.to_le() }
 
 /// Convert an u16 to big endian from the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "big")] #[inline] #[stable]
-pub fn to_be16(x: u16) -> u16 { x }
-
-/// Convert an u32 to big endian from the target's endianness.
-///
-/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] #[stable]
-pub fn to_be32(x: u32) -> u32 { unsafe { bswap32(x) } }
+#[inline]
+#[deprecated = "use `Int::to_be` instead"]
+pub fn to_be16(x: u16) -> u16 { x.to_be() }
 
 /// Convert an u32 to big endian from the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "big")] #[inline] #[stable]
-pub fn to_be32(x: u32) -> u32 { x }
-
-/// Convert an u64 to big endian from the target's endianness.
-///
-/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] #[stable]
-pub fn to_be64(x: u64) -> u64 { unsafe { bswap64(x) } }
+#[inline]
+#[deprecated = "use `Int::to_be` instead"]
+pub fn to_be32(x: u32) -> u32 { x.to_be() }
 
 /// Convert an u64 to big endian from the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "big")] #[inline] #[stable]
-pub fn to_be64(x: u64) -> u64 { x }
-
-
-/// Convert an u16 from little endian to the target's endianness.
-///
-/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] #[stable]
-pub fn from_le16(x: u16) -> u16 { x }
+#[inline]
+#[deprecated = "use `Int::to_be` instead"]
+pub fn to_be64(x: u64) -> u64 { x.to_be() }
 
 /// Convert an u16 from little endian to the target's endianness.
 ///
 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "big")] #[inline] #[stable]
-pub fn from_le16(x: u16) -> u16 { unsafe { bswap16(x) } }
-
-/// Convert an u32 from little endian to the target's endianness.
-///
-/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] #[stable]
-pub fn from_le32(x: u32) -> u32 { x }
+#[inline]
+#[deprecated = "use `Int::from_le` instead"]
+pub fn from_le16(x: u16) -> u16 { Int::from_le(x) }
 
 /// Convert an u32 from little endian to the target's endianness.
 ///
 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "big")] #[inline] #[stable]
-pub fn from_le32(x: u32) -> u32 { unsafe { bswap32(x) } }
-
-/// Convert an u64 from little endian to the target's endianness.
-///
-/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] #[stable]
-pub fn from_le64(x: u64) -> u64 { x }
+#[inline]
+#[deprecated = "use `Int::from_le` instead"]
+pub fn from_le32(x: u32) -> u32 { Int::from_le(x) }
 
 /// Convert an u64 from little endian to the target's endianness.
 ///
 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "big")] #[inline] #[stable]
-pub fn from_le64(x: u64) -> u64 { unsafe { bswap64(x) } }
-
-
-/// Convert an u16 from big endian to the target's endianness.
-///
-/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] #[stable]
-pub fn from_be16(x: u16) -> u16 { unsafe { bswap16(x) } }
+#[inline]
+#[deprecated = "use `Int::from_le` instead"]
+pub fn from_le64(x: u64) -> u64 { Int::from_le(x) }
 
 /// Convert an u16 from big endian to the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "big")] #[inline] #[stable]
-pub fn from_be16(x: u16) -> u16 { x }
-
-/// Convert an u32 from big endian to the target's endianness.
-///
-/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] #[stable]
-pub fn from_be32(x: u32) -> u32 { unsafe { bswap32(x) } }
+#[inline]
+#[deprecated = "use `Int::from_be` instead"]
+pub fn from_be16(x: u16) -> u16 { Int::from_be(x) }
 
 /// Convert an u32 from big endian to the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "big")] #[inline] #[stable]
-pub fn from_be32(x: u32) -> u32 { x }
-
-/// Convert an u64 from big endian to the target's endianness.
-///
-/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] #[stable]
-pub fn from_be64(x: u64) -> u64 { unsafe { bswap64(x) } }
+#[inline]
+#[deprecated = "use `Int::from_be` instead"]
+pub fn from_be32(x: u32) -> u32 { Int::from_be(x) }
 
 /// Convert an u64 from big endian to the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "big")] #[inline] #[stable]
-pub fn from_be64(x: u64) -> u64 { x }
+#[inline]
+#[deprecated = "use `Int::from_be` instead"]
+pub fn from_be64(x: u64) -> u64 { Int::from_be(x) }
 
-/**
- * Swap the values at two mutable locations of the same type, without
- * deinitialising or copying either one.
- */
+/// Swap the values at two mutable locations of the same type, without
+/// deinitialising or copying either one.
 #[inline]
 #[stable]
 pub fn swap<T>(x: &mut T, y: &mut T) {
@@ -337,42 +273,40 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
     }
 }
 
-/**
- * Replace the value at a mutable location with a new one, returning the old
- * value, without deinitialising or copying either one.
- *
- * This is primarily used for transferring and swapping ownership of a value
- * in a mutable location. For example, this function allows consumption of
- * one field of a struct by replacing it with another value. The normal approach
- * doesn't always work:
- *
- * ```rust,ignore
- * struct Buffer<T> { buf: Vec<T> }
- *
- * impl<T> Buffer<T> {
- *     fn get_and_reset(&mut self) -> Vec<T> {
- *         // error: cannot move out of dereference of `&mut`-pointer
- *         let buf = self.buf;
- *         self.buf = Vec::new();
- *         buf
- *     }
- * }
- * ```
- *
- * Note that `T` does not necessarily implement `Clone`, so it can't even
- * clone and reset `self.buf`. But `replace` can be used to disassociate
- * the original value of `self.buf` from `self`, allowing it to be returned:
- *
- * ```rust
- * # struct Buffer<T> { buf: Vec<T> }
- * impl<T> Buffer<T> {
- *     fn get_and_reset(&mut self) -> Vec<T> {
- *         use std::mem::replace;
- *         replace(&mut self.buf, Vec::new())
- *     }
- * }
- * ```
- */
+/// Replace the value at a mutable location with a new one, returning the old
+/// value, without deinitialising or copying either one.
+///
+/// This is primarily used for transferring and swapping ownership of a value
+/// in a mutable location. For example, this function allows consumption of
+/// one field of a struct by replacing it with another value. The normal approach
+/// doesn't always work:
+///
+/// ```rust,ignore
+/// struct Buffer<T> { buf: Vec<T> }
+///
+/// impl<T> Buffer<T> {
+///     fn get_and_reset(&mut self) -> Vec<T> {
+///         // error: cannot move out of dereference of `&mut`-pointer
+///         let buf = self.buf;
+///         self.buf = Vec::new();
+///         buf
+///     }
+/// }
+/// ```
+///
+/// Note that `T` does not necessarily implement `Clone`, so it can't even
+/// clone and reset `self.buf`. But `replace` can be used to disassociate
+/// the original value of `self.buf` from `self`, allowing it to be returned:
+///
+/// ```rust
+/// # struct Buffer<T> { buf: Vec<T> }
+/// impl<T> Buffer<T> {
+///     fn get_and_reset(&mut self) -> Vec<T> {
+///         use std::mem::replace;
+///         replace(&mut self.buf, Vec::new())
+///     }
+/// }
+/// ```
 #[inline]
 #[stable]
 pub fn replace<T>(dest: &mut T, mut src: T) -> T {
index 20bb12db694c0f1dcfbe5c1229ab26771829ffb0..79734324706b26e08dcffc1cb16bcdf061791763 100644 (file)
@@ -35,7 +35,6 @@ mod tests {
 
     use int;
     use num;
-    use num::Bitwise;
     use num::CheckedDiv;
 
     #[test]
@@ -90,7 +89,7 @@ fn test_is_negative() {
     }
 
     #[test]
-    fn test_bitwise() {
+    fn test_bitwise_operators() {
         assert!(0b1110 as $T == (0b1100 as $T).bitor(&(0b1010 as $T)));
         assert!(0b1000 as $T == (0b1100 as $T).bitand(&(0b1010 as $T)));
         assert!(0b0110 as $T == (0b1100 as $T).bitxor(&(0b1010 as $T)));
@@ -99,45 +98,74 @@ fn test_bitwise() {
         assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not());
     }
 
+    static A: $T = 0b0101100;
+    static B: $T = 0b0100001;
+    static C: $T = 0b1111001;
+
+    static _0: $T = 0;
+    static _1: $T = !0;
+
     #[test]
     fn test_count_ones() {
-        assert!((0b0101100 as $T).count_ones() == 3);
-        assert!((0b0100001 as $T).count_ones() == 2);
-        assert!((0b1111001 as $T).count_ones() == 5);
+        assert!(A.count_ones() == 3);
+        assert!(B.count_ones() == 2);
+        assert!(C.count_ones() == 5);
     }
 
     #[test]
     fn test_count_zeros() {
-        assert!((0b0101100 as $T).count_zeros() == BITS as $T - 3);
-        assert!((0b0100001 as $T).count_zeros() == BITS as $T - 2);
-        assert!((0b1111001 as $T).count_zeros() == BITS as $T - 5);
+        assert!(A.count_zeros() == BITS as $T - 3);
+        assert!(B.count_zeros() == BITS as $T - 2);
+        assert!(C.count_zeros() == BITS as $T - 5);
+    }
+
+    #[test]
+    fn test_rotate() {
+        assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
+        assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
+        assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
+
+        // Rotating these should make no difference
+        //
+        // We test using 124 bits because to ensure that overlong bit shifts do
+        // not cause undefined behaviour. See #10183.
+        assert_eq!(_0.rotate_left(124), _0);
+        assert_eq!(_1.rotate_left(124), _1);
+        assert_eq!(_0.rotate_right(124), _0);
+        assert_eq!(_1.rotate_right(124), _1);
     }
 
     #[test]
     fn test_swap_bytes() {
-        let n: $T = 0b0101100; assert_eq!(n.swap_bytes().swap_bytes(), n);
-        let n: $T = 0b0100001; assert_eq!(n.swap_bytes().swap_bytes(), n);
-        let n: $T = 0b1111001; assert_eq!(n.swap_bytes().swap_bytes(), n);
+        assert_eq!(A.swap_bytes().swap_bytes(), A);
+        assert_eq!(B.swap_bytes().swap_bytes(), B);
+        assert_eq!(C.swap_bytes().swap_bytes(), C);
 
         // Swapping these should make no difference
-        let n: $T = 0;   assert_eq!(n.swap_bytes(), n);
-        let n: $T = -1;  assert_eq!(n.swap_bytes(), n);
+        assert_eq!(_0.swap_bytes(), _0);
+        assert_eq!(_1.swap_bytes(), _1);
     }
 
     #[test]
-    fn test_rotate() {
-        let n: $T = 0b0101100; assert_eq!(n.rotate_left(6).rotate_right(2).rotate_right(4), n);
-        let n: $T = 0b0100001; assert_eq!(n.rotate_left(3).rotate_left(2).rotate_right(5),  n);
-        let n: $T = 0b1111001; assert_eq!(n.rotate_left(6).rotate_right(2).rotate_right(4), n);
+    fn test_le() {
+        assert_eq!(Int::from_le(A.to_le()), A);
+        assert_eq!(Int::from_le(B.to_le()), B);
+        assert_eq!(Int::from_le(C.to_le()), C);
+        assert_eq!(Int::from_le(_0), _0);
+        assert_eq!(Int::from_le(_1), _1);
+        assert_eq!(_0.to_le(), _0);
+        assert_eq!(_1.to_le(), _1);
+    }
 
-        // Rotating these should make no difference
-        //
-        // We test using 124 bits because to ensure that overlong bit shifts do
-        // not cause undefined behaviour. See #10183.
-        let n: $T = 0;   assert_eq!(n.rotate_left(124), n);
-        let n: $T = -1;  assert_eq!(n.rotate_left(124), n);
-        let n: $T = 0;   assert_eq!(n.rotate_right(124), n);
-        let n: $T = -1;  assert_eq!(n.rotate_right(124), n);
+    #[test]
+    fn test_be() {
+        assert_eq!(Int::from_be(A.to_be()), A);
+        assert_eq!(Int::from_be(B.to_be()), B);
+        assert_eq!(Int::from_be(C.to_be()), C);
+        assert_eq!(Int::from_be(_0), _0);
+        assert_eq!(Int::from_be(_1), _1);
+        assert_eq!(_0.to_be(), _0);
+        assert_eq!(_1.to_be(), _1);
     }
 
     #[test]
index eaa632be6d04c42fe749f39c1b5267fe945890de..573470c29bcf46af6cd25c4d4d3afed74c2c403f 100644 (file)
@@ -376,217 +376,293 @@ fn max_value() -> $t { $max }
 bounded_impl!(f32, f32::MIN_VALUE, f32::MAX_VALUE)
 bounded_impl!(f64, f64::MIN_VALUE, f64::MAX_VALUE)
 
-/// Numbers with a fixed binary representation.
-pub trait Bitwise: Bounded
-                 + Not<Self>
-                 + BitAnd<Self,Self>
-                 + BitOr<Self,Self>
-                 + BitXor<Self,Self>
-                 + Shl<Self,Self>
-                 + Shr<Self,Self> {
-    /// Returns the number of ones in the binary representation of the number.
+/// Specifies the available operations common to all of Rust's core numeric primitives.
+/// These may not always make sense from a purely mathematical point of view, but
+/// may be useful for systems programming.
+pub trait Primitive: Copy
+                   + Clone
+                   + Num
+                   + NumCast
+                   + PartialOrd
+                   + Bounded {}
+
+trait_impl!(Primitive for uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
+
+/// A primitive signed or unsigned integer equipped with various bitwise
+/// operators, bit counting methods, and endian conversion functions.
+pub trait Int: Primitive
+             + CheckedAdd
+             + CheckedSub
+             + CheckedMul
+             + CheckedDiv
+             + Bounded
+             + Not<Self>
+             + BitAnd<Self,Self>
+             + BitOr<Self,Self>
+             + BitXor<Self,Self>
+             + Shl<Self,Self>
+             + Shr<Self,Self> {
+    /// Returns the number of ones in the binary representation of the integer.
     ///
     /// # Example
     ///
     /// ```rust
-    /// use std::num::Bitwise;
-    ///
     /// let n = 0b01001100u8;
+    ///
     /// assert_eq!(n.count_ones(), 3);
     /// ```
-    fn count_ones(&self) -> Self;
+    fn count_ones(self) -> Self;
 
-    /// Returns the number of zeros in the binary representation of the number.
+    /// Returns the number of zeros in the binary representation of the integer.
     ///
     /// # Example
     ///
     /// ```rust
-    /// use std::num::Bitwise;
-    ///
     /// let n = 0b01001100u8;
+    ///
     /// assert_eq!(n.count_zeros(), 5);
     /// ```
     #[inline]
-    fn count_zeros(&self) -> Self {
-        (!*self).count_ones()
+    fn count_zeros(self) -> Self {
+        (!self).count_ones()
     }
 
     /// Returns the number of leading zeros in the in the binary representation
-    /// of the number.
+    /// of the integer.
     ///
     /// # Example
     ///
     /// ```rust
-    /// use std::num::Bitwise;
-    ///
     /// let n = 0b0101000u16;
+    ///
     /// assert_eq!(n.leading_zeros(), 10);
     /// ```
-    fn leading_zeros(&self) -> Self;
+    fn leading_zeros(self) -> Self;
 
     /// Returns the number of trailing zeros in the in the binary representation
-    /// of the number.
+    /// of the integer.
     ///
     /// # Example
     ///
     /// ```rust
-    /// use std::num::Bitwise;
-    ///
     /// let n = 0b0101000u16;
+    ///
     /// assert_eq!(n.trailing_zeros(), 3);
     /// ```
-    fn trailing_zeros(&self) -> Self;
+    fn trailing_zeros(self) -> Self;
 
-    /// Reverses the byte order of a binary number.
+    /// Shifts the bits to the left by a specified amount amount, `n`, wrapping
+    /// the truncated bits to the end of the resulting integer.
     ///
     /// # Example
     ///
     /// ```rust
-    /// use std::num::Bitwise;
+    /// let n = 0x0123456789ABCDEFu64;
+    /// let m = 0x3456789ABCDEF012u64;
+    ///
+    /// assert_eq!(n.rotate_left(12), m);
+    /// ```
+    fn rotate_left(self, n: uint) -> Self;
+
+    /// Shifts the bits to the right by a specified amount amount, `n`, wrapping
+    /// the truncated bits to the beginning of the resulting integer.
     ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let n = 0x0123456789ABCDEFu64;
+    /// let m = 0xDEF0123456789ABCu64;
+    ///
+    /// assert_eq!(n.rotate_right(12), m);
+    /// ```
+    fn rotate_right(self, n: uint) -> Self;
+
+    /// Reverses the byte order of the integer.
+    ///
+    /// # Example
+    ///
+    /// ```rust
     /// let n = 0x0123456789ABCDEFu64;
     /// let m = 0xEFCDAB8967452301u64;
+    ///
     /// assert_eq!(n.swap_bytes(), m);
     /// ```
-    fn swap_bytes(&self) -> Self;
+    fn swap_bytes(self) -> Self;
 
-    /// Shifts the bits to the left by a specified amount amount, `r`, wrapping
-    /// the truncated bits to the end of the resulting value.
+    /// Convert a integer from big endian to the target's endianness.
+    ///
+    /// On big endian this is a no-op. On little endian the bytes are swapped.
     ///
     /// # Example
     ///
     /// ```rust
-    /// use std::num::Bitwise;
+    /// let n = 0x0123456789ABCDEFu64;
+    ///
+    /// if cfg!(target_endian = "big") {
+    ///     assert_eq!(Int::from_be(n), n)
+    /// } else {
+    ///     assert_eq!(Int::from_be(n), n.swap_bytes())
+    /// }
+    /// ```
+    #[inline]
+    fn from_be(x: Self) -> Self {
+        if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
+    }
+
+    /// Convert a integer from little endian to the target's endianness.
+    ///
+    /// On little endian this is a no-op. On big endian the bytes are swapped.
     ///
+    /// # Example
+    ///
+    /// ```rust
     /// let n = 0x0123456789ABCDEFu64;
-    /// let m = 0x3456789ABCDEF012u64;
-    /// assert_eq!(n.rotate_left(12), m);
+    ///
+    /// if cfg!(target_endian = "little") {
+    ///     assert_eq!(Int::from_le(n), n)
+    /// } else {
+    ///     assert_eq!(Int::from_le(n), n.swap_bytes())
+    /// }
     /// ```
-    fn rotate_left(&self, r: uint) -> Self;
+    #[inline]
+    fn from_le(x: Self) -> Self {
+        if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
+    }
 
-    /// Shifts the bits to the right by a specified amount amount, `r`, wrapping
-    /// the truncated bits to the beginning of the resulting value.
+    /// Convert the integer to big endian from the target's endianness.
+    ///
+    /// On big endian this is a no-op. On little endian the bytes are swapped.
     ///
     /// # Example
     ///
     /// ```rust
-    /// use std::num::Bitwise;
+    /// let n = 0x0123456789ABCDEFu64;
+    ///
+    /// if cfg!(target_endian = "big") {
+    ///     assert_eq!(n.to_be(), n)
+    /// } else {
+    ///     assert_eq!(n.to_be(), n.swap_bytes())
+    /// }
+    /// ```
+    #[inline]
+    fn to_be(self) -> Self { // or not to be?
+        if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
+    }
+
+    /// Convert the integer to little endian from the target's endianness.
     ///
+    /// On little endian this is a no-op. On big endian the bytes are swapped.
+    ///
+    /// # Example
+    ///
+    /// ```rust
     /// let n = 0x0123456789ABCDEFu64;
-    /// let m = 0xDEF0123456789ABCu64;
-    /// assert_eq!(n.rotate_right(12), m);
+    ///
+    /// if cfg!(target_endian = "little") {
+    ///     assert_eq!(n.to_le(), n)
+    /// } else {
+    ///     assert_eq!(n.to_le(), n.swap_bytes())
+    /// }
     /// ```
-    fn rotate_right(&self, r: uint) -> Self;
+    #[inline]
+    fn to_le(self) -> Self {
+        if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
+    }
 }
 
-/// Swapping a single byte does nothing. This is unsafe to be consistent with
-/// the other `bswap` intrinsics.
-#[inline]
-unsafe fn bswap8(x: u8) -> u8 { x }
-
-macro_rules! bitwise_impl(
-    ($t:ty, $bits:expr, $co:ident, $lz:ident, $tz:ident, $bs:path) => {
-        impl Bitwise for $t {
+macro_rules! int_impl {
+    ($T:ty, $BITS:expr, $ctpop:path, $ctlz:path, $cttz:path, $bswap:path) => {
+        impl Int for $T {
             #[inline]
-            fn count_ones(&self) -> $t { unsafe { intrinsics::$co(*self) } }
+            fn count_ones(self) -> $T { unsafe { $ctpop(self) } }
 
             #[inline]
-            fn leading_zeros(&self) -> $t { unsafe { intrinsics::$lz(*self) } }
+            fn leading_zeros(self) -> $T { unsafe { $ctlz(self) } }
 
             #[inline]
-            fn trailing_zeros(&self) -> $t { unsafe { intrinsics::$tz(*self) } }
+            fn trailing_zeros(self) -> $T { unsafe { $cttz(self) } }
 
             #[inline]
-            fn swap_bytes(&self) -> $t { unsafe { $bs(*self) } }
+            fn rotate_left(self, n: uint) -> $T {
+                // Protect against undefined behaviour for over-long bit shifts
+                let n = n % $BITS;
+                (self << n) | (self >> ($BITS - n))
+            }
 
             #[inline]
-            fn rotate_left(&self, r: uint) -> $t {
-                // Protect against undefined behaviour for overlong bit shifts
-                let r = r % $bits;
-                (*self << r) | (*self >> ($bits - r))
+            fn rotate_right(self, n: uint) -> $T {
+                // Protect against undefined behaviour for over-long bit shifts
+                let n = n % $BITS;
+                (self >> n) | (self << ($BITS - n))
             }
 
             #[inline]
-            fn rotate_right(&self, r: uint) -> $t {
-                // Protect against undefined behaviour for overlong bit shifts
-                let r = r % $bits;
-                (*self >> r) | (*self << ($bits - r))
-            }
+            fn swap_bytes(self) -> $T { unsafe { $bswap(self) } }
         }
     }
-)
+}
+
+/// Swapping a single byte is a no-op. This is marked as `unsafe` for
+/// consistency with the other `bswap` intrinsics.
+unsafe fn bswap8(x: u8) -> u8 { x }
+
+int_impl!(u8, 8,
+    intrinsics::ctpop8,
+    intrinsics::ctlz8,
+    intrinsics::cttz8,
+    bswap8)
+
+int_impl!(u16, 16,
+    intrinsics::ctpop16,
+    intrinsics::ctlz16,
+    intrinsics::cttz16,
+    intrinsics::bswap16)
+
+int_impl!(u32, 32,
+    intrinsics::ctpop32,
+    intrinsics::ctlz32,
+    intrinsics::cttz32,
+    intrinsics::bswap32)
 
-macro_rules! bitwise_cast_impl(
-    ($t:ty, $t_cast:ty, $bits:expr,  $co:ident, $lz:ident, $tz:ident, $bs:path) => {
-        impl Bitwise for $t {
+int_impl!(u64, 64,
+    intrinsics::ctpop64,
+    intrinsics::ctlz64,
+    intrinsics::cttz64,
+    intrinsics::bswap64)
+
+macro_rules! int_cast_impl {
+    ($T:ty, $U:ty) => {
+        impl Int for $T {
             #[inline]
-            fn count_ones(&self) -> $t { unsafe { intrinsics::$co(*self as $t_cast) as $t } }
+            fn count_ones(self) -> $T { (self as $U).count_ones() as $T }
 
             #[inline]
-            fn leading_zeros(&self) -> $t { unsafe { intrinsics::$lz(*self as $t_cast) as $t } }
+            fn leading_zeros(self) -> $T { (self as $U).leading_zeros() as $T }
 
             #[inline]
-            fn trailing_zeros(&self) -> $t { unsafe { intrinsics::$tz(*self as $t_cast) as $t } }
+            fn trailing_zeros(self) -> $T { (self as $U).trailing_zeros() as $T }
 
             #[inline]
-            fn swap_bytes(&self) -> $t { unsafe { $bs(*self as $t_cast) as $t } }
+            fn rotate_left(self, n: uint) -> $T { (self as $U).rotate_left(n) as $T }
 
             #[inline]
-            fn rotate_left(&self, r: uint) -> $t {
-                // cast to prevent the sign bit from being corrupted
-                (*self as $t_cast).rotate_left(r) as $t
-            }
+            fn rotate_right(self, n: uint) -> $T { (self as $U).rotate_right(n) as $T }
 
             #[inline]
-            fn rotate_right(&self, r: uint) -> $t {
-                // cast to prevent the sign bit from being corrupted
-                (*self as $t_cast).rotate_right(r) as $t
-            }
+            fn swap_bytes(self) -> $T { (self as $U).swap_bytes() as $T }
         }
     }
-)
-
-#[cfg(target_word_size = "32")]
-bitwise_cast_impl!(uint, u32, 32, ctpop32, ctlz32, cttz32, intrinsics::bswap32)
-#[cfg(target_word_size = "64")]
-bitwise_cast_impl!(uint, u64, 64, ctpop64, ctlz64, cttz64, intrinsics::bswap64)
-
-bitwise_impl!(u8, 8, ctpop8, ctlz8, cttz8, bswap8)
-bitwise_impl!(u16, 16, ctpop16, ctlz16, cttz16, intrinsics::bswap16)
-bitwise_impl!(u32, 32, ctpop32, ctlz32, cttz32, intrinsics::bswap32)
-bitwise_impl!(u64, 64, ctpop64, ctlz64, cttz64, intrinsics::bswap64)
-
-#[cfg(target_word_size = "32")]
-bitwise_cast_impl!(int, u32, 32, ctpop32, ctlz32, cttz32, intrinsics::bswap32)
-#[cfg(target_word_size = "64")]
-bitwise_cast_impl!(int, u64, 64, ctpop64, ctlz64, cttz64, intrinsics::bswap64)
-
-bitwise_cast_impl!(i8, u8, 8, ctpop8, ctlz8, cttz8, bswap8)
-bitwise_cast_impl!(i16, u16, 16, ctpop16, ctlz16, cttz16, intrinsics::bswap16)
-bitwise_cast_impl!(i32, u32, 32, ctpop32, ctlz32, cttz32, intrinsics::bswap32)
-bitwise_cast_impl!(i64, u64, 64, ctpop64, ctlz64, cttz64, intrinsics::bswap64)
-
-/// Specifies the available operations common to all of Rust's core numeric primitives.
-/// These may not always make sense from a purely mathematical point of view, but
-/// may be useful for systems programming.
-pub trait Primitive: Copy
-                   + Clone
-                   + Num
-                   + NumCast
-                   + PartialOrd
-                   + Bounded {}
-
-trait_impl!(Primitive for uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
+}
 
-/// A collection of traits relevant to primitive signed and unsigned integers
-pub trait Int: Primitive
-             + Bitwise
-             + CheckedAdd
-             + CheckedSub
-             + CheckedMul
-             + CheckedDiv {}
+int_cast_impl!(i8, u8)
+int_cast_impl!(i16, u16)
+int_cast_impl!(i32, u32)
+int_cast_impl!(i64, u64)
 
-trait_impl!(Int for uint u8 u16 u32 u64 int i8 i16 i32 i64)
+#[cfg(target_word_size = "32")] int_cast_impl!(uint, u32)
+#[cfg(target_word_size = "64")] int_cast_impl!(uint, u64)
+#[cfg(target_word_size = "32")] int_cast_impl!(int, u32)
+#[cfg(target_word_size = "64")] int_cast_impl!(int, u64)
 
 /// Returns the smallest power of 2 greater than or equal to `n`.
 #[inline]
index 8e4ba10154244958dc6cef41e0c10af6f62e2c73..be1f960bcc3dffc50a8e0e1028d6bb94c82822df 100644 (file)
@@ -26,7 +26,6 @@ mod tests {
 
     use num;
     use num::CheckedDiv;
-    use num::Bitwise;
 
     #[test]
     fn test_overflows() {
@@ -41,7 +40,7 @@ fn test_num() {
     }
 
     #[test]
-    fn test_bitwise() {
+    fn test_bitwise_operators() {
         assert!(0b1110 as $T == (0b1100 as $T).bitor(&(0b1010 as $T)));
         assert!(0b1000 as $T == (0b1100 as $T).bitand(&(0b1010 as $T)));
         assert!(0b0110 as $T == (0b1100 as $T).bitxor(&(0b1010 as $T)));
@@ -50,45 +49,74 @@ fn test_bitwise() {
         assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not());
     }
 
+    static A: $T = 0b0101100;
+    static B: $T = 0b0100001;
+    static C: $T = 0b1111001;
+
+    static _0: $T = 0;
+    static _1: $T = !0;
+
     #[test]
     fn test_count_ones() {
-        assert!((0b0101100 as $T).count_ones() == 3);
-        assert!((0b0100001 as $T).count_ones() == 2);
-        assert!((0b1111001 as $T).count_ones() == 5);
+        assert!(A.count_ones() == 3);
+        assert!(B.count_ones() == 2);
+        assert!(C.count_ones() == 5);
     }
 
     #[test]
     fn test_count_zeros() {
-        assert!((0b0101100 as $T).count_zeros() == BITS as $T - 3);
-        assert!((0b0100001 as $T).count_zeros() == BITS as $T - 2);
-        assert!((0b1111001 as $T).count_zeros() == BITS as $T - 5);
+        assert!(A.count_zeros() == BITS as $T - 3);
+        assert!(B.count_zeros() == BITS as $T - 2);
+        assert!(C.count_zeros() == BITS as $T - 5);
+    }
+
+    #[test]
+    fn test_rotate() {
+        assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
+        assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
+        assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
+
+        // Rotating these should make no difference
+        //
+        // We test using 124 bits because to ensure that overlong bit shifts do
+        // not cause undefined behaviour. See #10183.
+        assert_eq!(_0.rotate_left(124), _0);
+        assert_eq!(_1.rotate_left(124), _1);
+        assert_eq!(_0.rotate_right(124), _0);
+        assert_eq!(_1.rotate_right(124), _1);
     }
 
     #[test]
     fn test_swap_bytes() {
-        let n: $T = 0b0101100; assert_eq!(n.swap_bytes().swap_bytes(), n);
-        let n: $T = 0b0100001; assert_eq!(n.swap_bytes().swap_bytes(), n);
-        let n: $T = 0b1111001; assert_eq!(n.swap_bytes().swap_bytes(), n);
+        assert_eq!(A.swap_bytes().swap_bytes(), A);
+        assert_eq!(B.swap_bytes().swap_bytes(), B);
+        assert_eq!(C.swap_bytes().swap_bytes(), C);
 
         // Swapping these should make no difference
-        let n: $T = 0;   assert_eq!(n.swap_bytes(), n);
-        let n: $T = MAX; assert_eq!(n.swap_bytes(), n);
+        assert_eq!(_0.swap_bytes(), _0);
+        assert_eq!(_1.swap_bytes(), _1);
     }
 
     #[test]
-    fn test_rotate() {
-        let n: $T = 0b0101100; assert_eq!(n.rotate_left(6).rotate_right(2).rotate_right(4), n);
-        let n: $T = 0b0100001; assert_eq!(n.rotate_left(3).rotate_left(2).rotate_right(5),  n);
-        let n: $T = 0b1111001; assert_eq!(n.rotate_left(6).rotate_right(2).rotate_right(4), n);
+    fn test_le() {
+        assert_eq!(Int::from_le(A.to_le()), A);
+        assert_eq!(Int::from_le(B.to_le()), B);
+        assert_eq!(Int::from_le(C.to_le()), C);
+        assert_eq!(Int::from_le(_0), _0);
+        assert_eq!(Int::from_le(_1), _1);
+        assert_eq!(_0.to_le(), _0);
+        assert_eq!(_1.to_le(), _1);
+    }
 
-        // Rotating these should make no difference
-        //
-        // We test using 124 bits because to ensure that overlong bit shifts do
-        // not cause undefined behaviour. See #10183.
-        let n: $T = 0;   assert_eq!(n.rotate_left(124), n);
-        let n: $T = MAX; assert_eq!(n.rotate_left(124), n);
-        let n: $T = 0;   assert_eq!(n.rotate_right(124), n);
-        let n: $T = MAX; assert_eq!(n.rotate_right(124), n);
+    #[test]
+    fn test_be() {
+        assert_eq!(Int::from_be(A.to_be()), A);
+        assert_eq!(Int::from_be(B.to_be()), B);
+        assert_eq!(Int::from_be(C.to_be()), C);
+        assert_eq!(Int::from_be(_0), _0);
+        assert_eq!(Int::from_be(_1), _1);
+        assert_eq!(_0.to_be(), _0);
+        assert_eq!(_1.to_be(), _1);
     }
 
     #[test]
index d27b0f0de7e30028745e7b789983afa8308900d9..4744d92436f2b75829dde916f5e8b7a52c6ce20d 100644 (file)
@@ -75,13 +75,13 @@ macro_rules! num_repr(($ty:ident, $suffix:expr) => (impl Repr for $ty {
     fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
         let s = self.to_str();
         writer.write(s.as_bytes()).and_then(|()| {
-            writer.write(bytes!($suffix))
+            writer.write($suffix)
         })
     }
 }))
 
-num_repr!(f32, "f32")
-num_repr!(f64, "f64")
+num_repr!(f32, b"f32")
+num_repr!(f64, b"f64")
 
 // New implementation using reflect::MovePtr
 
index 6c3ad8a6ef9611c63ac92007512aa06ae836d29d..ee25d19e324cc8e474ff5ff21057325113e5a326 100644 (file)
 //!
 //! # Using a scheduler pool
 //!
+//! This library adds a `GreenTaskBuilder` trait that extends the methods
+//! available on `std::task::TaskBuilder` to allow spawning a green task,
+//! possibly pinned to a particular scheduler thread:
+//!
 //! ```rust
-//! use std::rt::task::TaskOpts;
-//! use green::{SchedPool, PoolConfig};
-//! use green::sched::{PinnedTask, TaskFromFriend};
+//! use std::task::TaskBuilder;
+//! use green::{SchedPool, PoolConfig, GreenTaskBuilder};
 //!
 //! let config = PoolConfig::new();
 //! let mut pool = SchedPool::new(config);
 //!
 //! // Spawn tasks into the pool of schedulers
-//! pool.spawn(TaskOpts::new(), proc() {
+//! TaskBuilder::new().green(&mut pool).spawn(proc() {
 //!     // this code is running inside the pool of schedulers
 //!
 //!     spawn(proc() {
 //! let mut handle = pool.spawn_sched();
 //!
 //! // Pin a task to the spawned scheduler
-//! let task = pool.task(TaskOpts::new(), proc() { /* ... */ });
-//! handle.send(PinnedTask(task));
-//!
-//! // Schedule a task on this new scheduler
-//! let task = pool.task(TaskOpts::new(), proc() { /* ... */ });
-//! handle.send(TaskFromFriend(task));
+//! TaskBuilder::new().green_pinned(&mut pool, &mut handle).spawn(proc() {
+//!     /* ... */
+//! });
 //!
 //! // Handles keep schedulers alive, so be sure to drop all handles before
 //! // destroying the sched pool
 // NB this does *not* include globs, please keep it that way.
 #![feature(macro_rules, phase)]
 #![allow(visible_private_types)]
+#![allow(deprecated)]
+#![feature(default_type_params)]
 
 #[cfg(test)] #[phase(plugin, link)] extern crate log;
 #[cfg(test)] extern crate rustuv;
 use std::rt;
 use std::sync::atomics::{SeqCst, AtomicUint, INIT_ATOMIC_UINT};
 use std::sync::deque;
+use std::task::{TaskBuilder, Spawner};
 
-use sched::{Shutdown, Scheduler, SchedHandle, TaskFromFriend, NewNeighbor};
+use sched::{Shutdown, Scheduler, SchedHandle, TaskFromFriend, PinnedTask, NewNeighbor};
 use sleeper_list::SleeperList;
 use stack::StackPool;
 use task::GreenTask;
@@ -444,6 +447,7 @@ pub fn new(config: PoolConfig) -> SchedPool {
     /// This is useful to create a task which can then be sent to a specific
     /// scheduler created by `spawn_sched` (and possibly pin it to that
     /// scheduler).
+    #[deprecated = "use the green and green_pinned methods of GreenTaskBuilder instead"]
     pub fn task(&mut self, opts: TaskOpts, f: proc():Send) -> Box<GreenTask> {
         GreenTask::configure(&mut self.stack_pool, opts, f)
     }
@@ -454,6 +458,7 @@ pub fn task(&mut self, opts: TaskOpts, f: proc():Send) -> Box<GreenTask> {
     /// New tasks are spawned in a round-robin fashion to the schedulers in this
     /// pool, but tasks can certainly migrate among schedulers once they're in
     /// the pool.
+    #[deprecated = "use the green and green_pinned methods of GreenTaskBuilder instead"]
     pub fn spawn(&mut self, opts: TaskOpts, f: proc():Send) {
         let task = self.task(opts, f);
 
@@ -563,3 +568,54 @@ fn drop(&mut self) {
         }
     }
 }
+
+/// A spawner for green tasks
+pub struct GreenSpawner<'a>{
+    pool: &'a mut SchedPool,
+    handle: Option<&'a mut SchedHandle>
+}
+
+impl<'a> Spawner for GreenSpawner<'a> {
+    #[inline]
+    fn spawn(self, opts: TaskOpts, f: proc():Send) {
+        let GreenSpawner { pool, handle } = self;
+        match handle {
+            None    => pool.spawn(opts, f),
+            Some(h) => h.send(PinnedTask(pool.task(opts, f)))
+        }
+    }
+}
+
+/// An extension trait adding `green` configuration methods to `TaskBuilder`.
+pub trait GreenTaskBuilder {
+    fn green<'a>(self, &'a mut SchedPool) -> TaskBuilder<GreenSpawner<'a>>;
+    fn green_pinned<'a>(self, &'a mut SchedPool, &'a mut SchedHandle)
+                        -> TaskBuilder<GreenSpawner<'a>>;
+}
+
+impl<S: Spawner> GreenTaskBuilder for TaskBuilder<S> {
+    fn green<'a>(self, pool: &'a mut SchedPool) -> TaskBuilder<GreenSpawner<'a>> {
+        self.spawner(GreenSpawner {pool: pool, handle: None})
+    }
+
+    fn green_pinned<'a>(self, pool: &'a mut SchedPool, handle: &'a mut SchedHandle)
+                        -> TaskBuilder<GreenSpawner<'a>> {
+        self.spawner(GreenSpawner {pool: pool, handle: Some(handle)})
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use std::task::TaskBuilder;
+    use super::{SchedPool, PoolConfig, GreenTaskBuilder};
+
+    #[test]
+    fn test_green_builder() {
+        let mut pool = SchedPool::new(PoolConfig::new());
+        let res = TaskBuilder::new().green(&mut pool).try(proc() {
+            "Success!".to_string()
+        });
+        assert_eq!(res.ok().unwrap(), "Success!".to_string());
+        pool.shutdown();
+    }
+}
index 93938e3d5b860925fbb6b4e69e07ccd21e0d15c6..edf2becc777608584821035107beb20f7f764454 100644 (file)
@@ -360,7 +360,7 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<CString> {
         let root = Path::new(root);
 
         dirs.move_iter().filter(|path| {
-            path.as_vec() != bytes!(".") && path.as_vec() != bytes!("..")
+            path.as_vec() != b"." && path.as_vec() != b".."
         }).map(|path| root.join(path).to_c_str()).collect()
     }
 
@@ -529,7 +529,7 @@ fn test_file_desc() {
         let mut reader = FileDesc::new(reader, true);
         let mut writer = FileDesc::new(writer, true);
 
-        writer.inner_write(bytes!("test")).ok().unwrap();
+        writer.inner_write(b"test").ok().unwrap();
         let mut buf = [0u8, ..4];
         match reader.inner_read(buf) {
             Ok(4) => {
@@ -552,7 +552,7 @@ fn test_cfile() {
             assert!(!f.is_null());
             let mut file = CFile::new(f);
 
-            file.write(bytes!("test")).ok().unwrap();
+            file.write(b"test").ok().unwrap();
             let mut buf = [0u8, ..4];
             let _ = file.seek(0, SeekSet).ok().unwrap();
             match file.read(buf) {
index 41ef5e31a91f65cad24549a9bd3c649c0921083e..cd9abc70a4ee8cd09690be4ff6a45d276021e39a 100644 (file)
@@ -351,7 +351,7 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<CString> {
         let root = Path::new(root);
 
         dirs.move_iter().filter(|path| {
-            path.as_vec() != bytes!(".") && path.as_vec() != bytes!("..")
+            path.as_vec() != b"." && path.as_vec() != b".."
         }).map(|path| root.join(path).to_c_str()).collect()
     }
 
index 8cf0c3bf0620f82d72b7b0cb36f4847ee959424a..5dfae8d9efe649b5221b176dad416371c3504952 100644 (file)
 #[cfg(unix)]    pub type sock_t = super::file::fd_t;
 
 pub fn htons(u: u16) -> u16 {
-    mem::to_be16(u)
+    u.to_be()
 }
 pub fn ntohs(u: u16) -> u16 {
-    mem::from_be16(u)
+    Int::from_be(u)
 }
 
 enum InAddr {
@@ -46,7 +46,7 @@ fn ip_to_inaddr(ip: rtio::IpAddr) -> InAddr {
                      (c as u32 <<  8) |
                      (d as u32 <<  0);
             InAddr(libc::in_addr {
-                s_addr: mem::from_be32(ip)
+                s_addr: Int::from_be(ip)
             })
         }
         rtio::Ipv6Addr(a, b, c, d, e, f, g, h) => {
@@ -180,7 +180,7 @@ pub fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
             let storage: &libc::sockaddr_in = unsafe {
                 mem::transmute(storage)
             };
-            let ip = mem::to_be32(storage.sin_addr.s_addr as u32);
+            let ip = (storage.sin_addr.s_addr as u32).to_be();
             let a = (ip >> 24) as u8;
             let b = (ip >> 16) as u8;
             let c = (ip >>  8) as u8;
index f04dfac80ccfe54c252d7c2b08fe4da6c9dcd9b6..40b99c5bbdb1d0bb08d4d948cf5c46e1024a959e 100644 (file)
 //! ```rust
 //! extern crate native;
 //!
+//! use std::task::TaskBuilder;
+//! use native::NativeTaskBuilder;
+//!
 //! fn main() {
 //!     // We're not sure whether this main function is run in 1:1 or M:N mode.
 //!
-//!     native::task::spawn(proc() {
+//!     TaskBuilder::new().native().spawn(proc() {
 //!         // this code is guaranteed to be run on a native thread
 //!     });
 //! }
@@ -50,7 +53,8 @@
        html_root_url = "http://doc.rust-lang.org/")]
 #![deny(unused_result, unused_must_use)]
 #![allow(non_camel_case_types)]
-#![feature(macro_rules)]
+#![allow(deprecated)]
+#![feature(default_type_params)]
 
 // NB this crate explicitly does *not* allow glob imports, please seriously
 //    consider whether they're needed before adding that feature here (the
@@ -65,6 +69,8 @@
 use std::rt;
 use std::str;
 
+pub use task::NativeTaskBuilder;
+
 pub mod io;
 pub mod task;
 
index b073c2c7fbf026f8ecfe52b3a1065279315c3bb7..88e581a47913674ae1e926e3c0a001a562f30e45 100644 (file)
@@ -27,6 +27,7 @@
 
 use io;
 use task;
+use std::task::{TaskBuilder, Spawner};
 
 /// Creates a new Task which is ready to execute as a 1:1 task.
 pub fn new(stack_bounds: (uint, uint)) -> Box<Task> {
@@ -48,12 +49,14 @@ fn ops() -> Box<Ops> {
 }
 
 /// Spawns a function with the default configuration
+#[deprecated = "use the native method of NativeTaskBuilder instead"]
 pub fn spawn(f: proc():Send) {
     spawn_opts(TaskOpts { name: None, stack_size: None, on_exit: None }, f)
 }
 
 /// Spawns a new task given the configuration options and a procedure to run
 /// inside the task.
+#[deprecated = "use the native method of NativeTaskBuilder instead"]
 pub fn spawn_opts(opts: TaskOpts, f: proc():Send) {
     let TaskOpts { name, stack_size, on_exit } = opts;
 
@@ -95,6 +98,26 @@ pub fn spawn_opts(opts: TaskOpts, f: proc():Send) {
     })
 }
 
+/// A spawner for native tasks
+pub struct NativeSpawner;
+
+impl Spawner for NativeSpawner {
+    fn spawn(self, opts: TaskOpts, f: proc():Send) {
+        spawn_opts(opts, f)
+    }
+}
+
+/// An extension trait adding a `native` configuration method to `TaskBuilder`.
+pub trait NativeTaskBuilder {
+    fn native(self) -> TaskBuilder<NativeSpawner>;
+}
+
+impl<S: Spawner> NativeTaskBuilder for TaskBuilder<S> {
+    fn native(self) -> TaskBuilder<NativeSpawner> {
+        self.spawner(NativeSpawner)
+    }
+}
+
 // This structure is the glue between channels and the 1:1 scheduling mode. This
 // structure is allocated once per task.
 struct Ops {
@@ -259,7 +282,8 @@ mod tests {
     use std::rt::local::Local;
     use std::rt::task::{Task, TaskOpts};
     use std::task;
-    use super::{spawn, spawn_opts, Ops};
+    use std::task::TaskBuilder;
+    use super::{spawn, spawn_opts, Ops, NativeTaskBuilder};
 
     #[test]
     fn smoke() {
@@ -347,4 +371,12 @@ fn spawn_inherits() {
         });
         rx.recv();
     }
+
+    #[test]
+    fn test_native_builder() {
+        let res = TaskBuilder::new().native().try(proc() {
+            "Success!".to_string()
+        });
+        assert_eq!(res.ok().unwrap(), "Success!".to_string());
+    }
 }
index 0933301970d1969a3901a1c9f6b196107653e7b4..e9153f89e04ee8d12aad9b6c5e6a00e161b3a9b7 100644 (file)
@@ -23,7 +23,7 @@
 use std::default::Default;
 use std::from_str::FromStr;
 use std::num::CheckedDiv;
-use std::num::{Bitwise, ToPrimitive, FromPrimitive};
+use std::num::{ToPrimitive, FromPrimitive};
 use std::num::{Zero, One, ToStrRadix, FromStrRadix};
 use std::string::String;
 use std::{uint, i64, u64};
index 5a9b949be251ac6e0413130443a5da7ad41771bd..048e44cd55d78098ee98da8dfebaf3ee1ab05fcd 100644 (file)
@@ -292,9 +292,9 @@ pub struct AsciiGenerator<'a, R> {
 impl<'a, R: Rng> Iterator<char> for AsciiGenerator<'a, R> {
     fn next(&mut self) -> Option<char> {
         static GEN_ASCII_STR_CHARSET: &'static [u8] =
-            bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZ\
-                    abcdefghijklmnopqrstuvwxyz\
-                    0123456789");
+            b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+              abcdefghijklmnopqrstuvwxyz\
+              0123456789";
         Some(*self.rng.choose(GEN_ASCII_STR_CHARSET).unwrap() as char)
     }
 }
index ada65394e1923721d8d685306a55c9f09c2593f7..f55fd78762c5dbaa093a1e5efc3af153846c79b5 100644 (file)
@@ -366,22 +366,19 @@ fn monitor(f: proc():Send) {
     #[cfg(not(rtopt))]
     static STACK_SIZE: uint = 20000000; // 20MB
 
-    let mut task_builder = TaskBuilder::new().named("rustc");
+    let (tx, rx) = channel();
+    let w = io::ChanWriter::new(tx);
+    let mut r = io::ChanReader::new(rx);
+
+    let mut task = TaskBuilder::new().named("rustc").stderr(box w);
 
     // FIXME: Hacks on hacks. If the env is trying to override the stack size
     // then *don't* set it explicitly.
     if os::getenv("RUST_MIN_STACK").is_none() {
-        task_builder.opts.stack_size = Some(STACK_SIZE);
+        task = task.stack_size(STACK_SIZE);
     }
 
-    let (tx, rx) = channel();
-    let w = io::ChanWriter::new(tx);
-    let mut r = io::ChanReader::new(rx);
-
-    match task_builder.try(proc() {
-        io::stdio::set_stderr(box w);
-        f()
-    }) {
+    match task.try(f) {
         Ok(()) => { /* fallthrough */ }
         Err(value) => {
             // Task failed without emitting a fatal diagnostic
index ec46e7f8592d3391ffbc4e69e101bf47df625e61..c15148f75df2242b9c5915ac113f1ac5d14ec811 100644 (file)
@@ -214,7 +214,7 @@ pub fn rust_path() -> Vec<Path> {
         env_rust_path.push(cwd.clone());
     }
     loop {
-        if { let f = cwd.filename(); f.is_none() || f.unwrap() == bytes!("..") } {
+        if { let f = cwd.filename(); f.is_none() || f.unwrap() == b".." } {
             break
         }
         cwd.set_filename(".rust");
index bb92043b1ea6a42e7a99dd7725fbd4070a28a922..b61596908e60a5f93ea3307e463e44bd7fe42e98 100644 (file)
@@ -25,6 +25,7 @@
 use middle::dataflow::BitwiseOperator;
 use middle::dataflow::DataFlowOperator;
 use euv = middle::expr_use_visitor;
+use mc = middle::mem_categorization;
 use middle::ty;
 use syntax::ast;
 use syntax::ast_util;
@@ -160,6 +161,22 @@ pub struct Assignment {
 
 pub type AssignDataFlow<'a> = DataFlowContext<'a, AssignDataFlowOperator>;
 
+fn loan_path_is_precise(loan_path: &LoanPath) -> bool {
+    match *loan_path {
+        LpVar(_) | LpUpvar(_) => {
+            true
+        }
+        LpExtend(_, _, LpInterior(mc::InteriorElement(_))) => {
+            // Paths involving element accesses do not refer to a unique
+            // location, as there is no accurate tracking of the indices.
+            false
+        }
+        LpExtend(ref lp_base, _, _) => {
+            loan_path_is_precise(&**lp_base)
+        }
+    }
+}
+
 impl MoveData {
     pub fn new() -> MoveData {
         MoveData {
@@ -500,10 +517,17 @@ fn kill_moves(&self,
                   path: MovePathIndex,
                   kill_id: ast::NodeId,
                   dfcx_moves: &mut MoveDataFlow) {
-        self.each_applicable_move(path, |move_index| {
-            dfcx_moves.add_kill(kill_id, move_index.get());
-            true
-        });
+        // We can only perform kills for paths that refer to a unique location,
+        // since otherwise we may kill a move from one location with an
+        // assignment referring to another location.
+
+        let loan_path = self.path_loan_path(path);
+        if loan_path_is_precise(&*loan_path) {
+            self.each_applicable_move(path, |move_index| {
+                dfcx_moves.add_kill(kill_id, move_index.get());
+                true
+            });
+        }
     }
 }
 
index cd876113807a973acd94f122686f72def9f9bf02..8cd840582ba999d13ac96e350562ba79be6a214e 100644 (file)
@@ -701,17 +701,12 @@ fn find_loop_scope(&self,
                 if self.loop_scope.len() == 0 {
                     self.ir.tcx.sess.span_bug(sp, "break outside loop");
                 } else {
-                    // FIXME(#5275): this shouldn't have to be a method...
-                    self.last_loop_scope()
+                    *self.loop_scope.last().unwrap()
                 }
             }
         }
     }
 
-    fn last_loop_scope(&self) -> NodeId {
-        *self.loop_scope.last().unwrap()
-    }
-
     #[allow(unused_must_use)]
     fn ln_str(&self, ln: LiveNode) -> String {
         let mut wr = io::MemWriter::new();
index 808d894be43869234976875d2c3ce2f6b32125be..ffd29ffeb8fb42797b013d5430aea9bc402d6226 100644 (file)
@@ -518,8 +518,7 @@ fn enter_default<'a, 'b>(
                  dm: &DefMap,
                  m: &'a [Match<'a, 'b>],
                  col: uint,
-                 val: ValueRef,
-                 chk: &FailureHandler)
+                 val: ValueRef)
                  -> Vec<Match<'a, 'b>> {
     debug!("enter_default(bcx={}, m={}, col={}, val={})",
            bcx.to_str(),
@@ -529,35 +528,13 @@ fn enter_default<'a, 'b>(
     let _indenter = indenter();
 
     // Collect all of the matches that can match against anything.
-    let matches = enter_match(bcx, dm, m, col, val, |p| {
+    enter_match(bcx, dm, m, col, val, |p| {
         match p.node {
           ast::PatWild | ast::PatWildMulti => Some(Vec::new()),
           ast::PatIdent(_, _, None) if pat_is_binding(dm, &*p) => Some(Vec::new()),
           _ => None
         }
-    });
-
-    // Ok, now, this is pretty subtle. A "default" match is a match
-    // that needs to be considered if none of the actual checks on the
-    // value being considered succeed. The subtlety lies in that sometimes
-    // identifier/wildcard matches are *not* default matches. Consider:
-    // "match x { _ if something => foo, true => bar, false => baz }".
-    // There is a wildcard match, but it is *not* a default case. The boolean
-    // case on the value being considered is exhaustive. If the case is
-    // exhaustive, then there are no defaults.
-    //
-    // We detect whether the case is exhaustive in the following
-    // somewhat kludgy way: if the last wildcard/binding match has a
-    // guard, then by non-redundancy, we know that there aren't any
-    // non guarded matches, and thus by exhaustiveness, we know that
-    // we don't need any default cases. If the check *isn't* nonexhaustive
-    // (because chk is Some), then we need the defaults anyways.
-    let is_exhaustive = match matches.last() {
-        Some(m) if m.data.arm.guard.is_some() && chk.is_infallible() => true,
-        _ => false
-    };
-
-    if is_exhaustive { Vec::new() } else { matches }
+    })
 }
 
 // <pcwalton> nmatsakis: what does enter_opt do?
@@ -1448,15 +1425,12 @@ fn compile_submatch<'a, 'b>(
            m.repr(bcx.tcx()),
            vec_map_to_str(vals, |v| bcx.val_to_str(*v)));
     let _indenter = indenter();
-
-    /*
-      For an empty match, a fall-through case must exist
-     */
-    assert!((m.len() > 0u || chk.is_fallible()));
     let _icx = push_ctxt("match::compile_submatch");
     let mut bcx = bcx;
     if m.len() == 0u {
-        Br(bcx, chk.handle_fail());
+        if chk.is_fallible() {
+            Br(bcx, chk.handle_fail());
+        }
         return;
     }
     if m[0].pats.len() == 0u {
@@ -1658,7 +1632,7 @@ fn compile_submatch_continue<'a, 'b>(
         C_int(ccx, 0) // Placeholder for when not using a switch
     };
 
-    let defaults = enter_default(else_cx, dm, m, col, val, chk);
+    let defaults = enter_default(else_cx, dm, m, col, val);
     let exhaustive = chk.is_infallible() && defaults.len() == 0u;
     let len = opts.len();
 
@@ -1947,18 +1921,14 @@ fn trans_match_inner<'a>(scope_cx: &'a Block<'a>,
 
     // `compile_submatch` works one column of arm patterns a time and
     // then peels that column off. So as we progress, it may become
-    // impossible to know whether we have a genuine default arm, i.e.
+    // impossible to tell whether we have a genuine default arm, i.e.
     // `_ => foo` or not. Sometimes it is important to know that in order
     // to decide whether moving on to the next condition or falling back
     // to the default arm.
-    let has_default = arms.len() > 0 && {
-        let ref pats = arms.last().unwrap().pats;
-
-        pats.len() == 1
-        && match pats.last().unwrap().node {
-            ast::PatWild => true, _ => false
-        }
-    };
+    let has_default = arms.last().map_or(false, |arm| {
+        arm.pats.len() == 1
+        && arm.pats.last().unwrap().node == ast::PatWild
+    });
 
     compile_submatch(bcx, matches.as_slice(), [discr_datum.val], &chk, has_default);
 
index 9f4b11116dbb74717cbc27e984c576fada5e63c3..e4b28dc7aa7c2607272577259f702b870d1826fe 100644 (file)
@@ -46,7 +46,6 @@
 #![allow(unsigned_negate)]
 
 use libc::c_ulonglong;
-use std::num::{Bitwise};
 use std::rc::Rc;
 
 use lib::llvm::{ValueRef, True, IntEQ, IntNE};
index 11166f92b1cc2629229b0d7e3f8b2f2bf770649d..783fdfa4aaec911145cb432fbb8c4fae5f278f74 100644 (file)
@@ -1411,7 +1411,7 @@ fn compile_unit_metadata(cx: &CrateContext) {
                 match abs_path.path_relative_from(work_dir) {
                     Some(ref p) if p.is_relative() => {
                             // prepend "./" if necessary
-                            let dotdot = bytes!("..");
+                            let dotdot = b"..";
                             let prefix = &[dotdot[0], ::std::path::SEP_BYTE];
                             let mut path_bytes = Vec::from_slice(p.as_vec());
 
index 42c7a71bab84dbda7bc4f9b3b454d9eeb3baf7c0..599b45aafe20d1a488532372cf33fbf47292dc45 100644 (file)
@@ -1463,7 +1463,7 @@ fn trans_overloaded_call<'a>(
     // Evaluate and tuple the arguments.
     let tuple_type = ty::mk_tup(bcx.tcx(),
                                 args.iter()
-                                    .map(|e| expr_ty(bcx, &**e))
+                                    .map(|e| ty::expr_ty_adjusted(bcx.tcx(), &**e))
                                     .collect());
     let repr = adt::represent_type(bcx.ccx(), tuple_type);
     let numbered_fields: Vec<(uint, Gc<ast::Expr>)> =
index f48a93574e7e75715dacb3fd4aea5862b2936d1b..0304a1d690ef5ef620a9b7842073fad19cc722d5 100644 (file)
@@ -63,7 +63,7 @@ pub fn render<T: fmt::Show, S: fmt::Show>(
             <div class="search-container">
                 <input class="search-input" name="search"
                        autocomplete="off"
-                       placeholder="Search documentation..."
+                       placeholder="Click or press 's' to search, '?' for more options..."
                        type="search">
             </div>
         </form>
index c6a6eb29addda9547d98dea42034b32dfeb54411..76e604ecfa287569dc0adfc75d23a3860c6695ae 100644 (file)
@@ -602,7 +602,7 @@ fn mkdir(path: &Path) -> io::IoResult<()> {
 // FIXME (#9639): The closure should deal with &[u8] instead of &str
 fn clean_srcpath(src: &[u8], f: |&str|) {
     let p = Path::new(src);
-    if p.as_vec() != bytes!(".") {
+    if p.as_vec() != b"." {
         for c in p.str_components().map(|x|x.unwrap()) {
             if ".." == c {
                 f("up");
@@ -714,7 +714,7 @@ fn emit_source(&mut self, filename: &str) -> io::IoResult<()> {
         });
 
         cur.push(Vec::from_slice(p.filename().expect("source has no filename"))
-                 .append(bytes!(".html")));
+                 .append(b".html"));
         let mut w = BufferedWriter::new(try!(File::create(&cur)));
 
         let title = format!("{} -- source", cur.filename_display());
index d6d4b18051bf3e54ffaad90c02f75cf67810ab99..09ae2b31f6368d2c16d7bdc9d82cb148d98daf4c 100644 (file)
@@ -123,8 +123,8 @@ fn smoke_test() {
             let saved_value = take();
 
             let expected = vec![
-                Vec::from_slice(bytes!("happy")),
-                Vec::from_slice(bytes!("today?")),
+                Vec::from_slice(b"happy"),
+                Vec::from_slice(b"today?"),
             ];
 
             put(expected.clone());
index b4d9ac7efbebcce50deb04af89445f41f9756a37..4a7ac97beed8d6f1060add48110e87b6a37ac58d 100644 (file)
@@ -463,7 +463,7 @@ mod tests {
     #[test]
     fn test_str_multistring_parsing() {
         unsafe {
-            let input = bytes!("zero", "\x00", "one", "\x00", "\x00");
+            let input = b"zero\0one\0\0";
             let ptr = input.as_ptr();
             let expected = ["zero", "one"];
             let mut it = expected.iter();
@@ -505,7 +505,7 @@ fn test_vec_to_c_str() {
             }
         });
 
-        let _ = bytes!("hello").to_c_str().with_ref(|buf| {
+        let _ = b"hello".to_c_str().with_ref(|buf| {
             unsafe {
                 assert_eq!(*buf.offset(0), 'h' as libc::c_char);
                 assert_eq!(*buf.offset(1), 'e' as libc::c_char);
@@ -516,7 +516,7 @@ fn test_vec_to_c_str() {
             }
         });
 
-        let _ = bytes!("foo", 0xff).to_c_str().with_ref(|buf| {
+        let _ = b"foo\xFF".to_c_str().with_ref(|buf| {
             unsafe {
                 assert_eq!(*buf.offset(0), 'f' as libc::c_char);
                 assert_eq!(*buf.offset(1), 'o' as libc::c_char);
@@ -595,22 +595,22 @@ fn test_to_c_str_unchecked() {
     #[test]
     fn test_as_bytes() {
         let c_str = "hello".to_c_str();
-        assert_eq!(c_str.as_bytes(), bytes!("hello", 0));
+        assert_eq!(c_str.as_bytes(), b"hello\0");
         let c_str = "".to_c_str();
-        assert_eq!(c_str.as_bytes(), bytes!(0));
-        let c_str = bytes!("foo", 0xff).to_c_str();
-        assert_eq!(c_str.as_bytes(), bytes!("foo", 0xff, 0));
+        assert_eq!(c_str.as_bytes(), b"\0");
+        let c_str = b"foo\xFF".to_c_str();
+        assert_eq!(c_str.as_bytes(), b"foo\xFF\0");
     }
 
     #[test]
     fn test_as_bytes_no_nul() {
         let c_str = "hello".to_c_str();
-        assert_eq!(c_str.as_bytes_no_nul(), bytes!("hello"));
+        assert_eq!(c_str.as_bytes_no_nul(), b"hello");
         let c_str = "".to_c_str();
         let exp: &[u8] = [];
         assert_eq!(c_str.as_bytes_no_nul(), exp);
-        let c_str = bytes!("foo", 0xff).to_c_str();
-        assert_eq!(c_str.as_bytes_no_nul(), bytes!("foo", 0xff));
+        let c_str = b"foo\xFF".to_c_str();
+        assert_eq!(c_str.as_bytes_no_nul(), b"foo\xFF");
     }
 
     #[test]
@@ -633,7 +633,7 @@ fn test_as_str() {
         assert_eq!(c_str.as_str(), Some("hello"));
         let c_str = "".to_c_str();
         assert_eq!(c_str.as_str(), Some(""));
-        let c_str = bytes!("foo", 0xff).to_c_str();
+        let c_str = b"foo\xFF".to_c_str();
         assert_eq!(c_str.as_str(), None);
     }
 
index c8fb0f496dcb72182d931114d5a8e81aef9b1c22..82693acb1e9dc9573698ad23540aec33b5ec76e1 100644 (file)
@@ -30,8 +30,8 @@
 /// Generic functions related to dealing with sockaddr things
 ////////////////////////////////////////////////////////////////////////////////
 
-pub fn htons(u: u16) -> u16 { mem::to_be16(u) }
-pub fn ntohs(u: u16) -> u16 { mem::from_be16(u) }
+pub fn htons(u: u16) -> u16 { u.to_be() }
+pub fn ntohs(u: u16) -> u16 { Int::from_be(u) }
 
 pub fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
                         len: uint) -> rtio::SocketAddr {
@@ -41,7 +41,7 @@ pub fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
             let storage: &libc::sockaddr_in = unsafe {
                 mem::transmute(storage)
             };
-            let ip = mem::to_be32(storage.sin_addr.s_addr as u32);
+            let ip = (storage.sin_addr.s_addr as u32).to_be();
             let a = (ip >> 24) as u8;
             let b = (ip >> 16) as u8;
             let c = (ip >>  8) as u8;
@@ -89,7 +89,8 @@ fn addr_to_sockaddr(addr: rtio::SocketAddr) -> (libc::sockaddr_storage, uint) {
                 (*storage).sin_family = libc::AF_INET as libc::sa_family_t;
                 (*storage).sin_port = htons(addr.port);
                 (*storage).sin_addr = libc::in_addr {
-                    s_addr: mem::from_be32(ip)
+                    s_addr: Int::from_be(ip),
+
                 };
                 mem::size_of::<libc::sockaddr_in>()
             }
index 5a8759540c8b5655fbc86dda7034868905b36149..5c4da38989f11316b8a1ad2820b500528773b78b 100644 (file)
@@ -42,13 +42,13 @@ pub struct Config {
 pub static MIME: Config =
     Config {char_set: Standard, pad: true, line_length: Some(76)};
 
-static STANDARD_CHARS: &'static[u8] = bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZ",
-                                             "abcdefghijklmnopqrstuvwxyz",
-                                             "0123456789+/");
+static STANDARD_CHARS: &'static[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+                                        abcdefghijklmnopqrstuvwxyz\
+                                        0123456789+/";
 
-static URLSAFE_CHARS: &'static[u8] = bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZ",
-                                            "abcdefghijklmnopqrstuvwxyz",
-                                            "0123456789-_");
+static URLSAFE_CHARS: &'static[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+                                       abcdefghijklmnopqrstuvwxyz\
+                                       0123456789-_";
 
 /// A trait for converting a value to base64 encoding.
 pub trait ToBase64 {
@@ -193,7 +193,7 @@ impl<'a> FromBase64 for &'a str {
      * use serialize::base64::{ToBase64, FromBase64, STANDARD};
      *
      * fn main () {
-     *     let hello_str = bytes!("Hello, World").to_base64(STANDARD);
+     *     let hello_str = b"Hello, World".to_base64(STANDARD);
      *     println!("base64 output: {}", hello_str);
      *     let res = hello_str.as_slice().from_base64();
      *     if res.is_ok() {
index 9ba2c2cd258ed0dc5643a87acd30385b7246b25f..12c5a3493c17bcd1091f4f8fff583eb8f18ae508 100644 (file)
@@ -154,8 +154,6 @@ fn vuint_at_slow(data: &[u8], start: uint) -> DecodeResult<Res> {
     }
 
     pub fn vuint_at(data: &[u8], start: uint) -> DecodeResult<Res> {
-        use std::mem::from_be32;
-
         if data.len() - start < 4 {
             return vuint_at_slow(data, start);
         }
@@ -185,7 +183,7 @@ pub fn vuint_at(data: &[u8], start: uint) -> DecodeResult<Res> {
 
         unsafe {
             let ptr = data.as_ptr().offset(start as int) as *u32;
-            let val = from_be32(*ptr);
+            let val = Int::from_be(*ptr);
 
             let i = (val >> 28u) as uint;
             let (shift, mask) = SHIFT_MASK_TABLE[i];
index 8ae3336c342b4aed27428b04efcf1a5355b45f9d..44d0606185345be24ff6eea88a2fd849ec48c85e 100644 (file)
@@ -19,7 +19,7 @@ pub trait ToHex {
     fn to_hex(&self) -> String;
 }
 
-static CHARS: &'static[u8] = bytes!("0123456789abcdef");
+static CHARS: &'static[u8] = b"0123456789abcdef";
 
 impl<'a> ToHex for &'a [u8] {
     /**
index 9450f7798edcf97c3db3c59cde615ffea6eec4b0..4f355502eb88d3a9d5b742f2e91942722bbc5cdc 100644 (file)
@@ -535,7 +535,7 @@ fn test_line_buffer() {
 
     #[test]
     fn test_read_line() {
-        let in_buf = MemReader::new(Vec::from_slice(bytes!("a\nb\nc")));
+        let in_buf = MemReader::new(Vec::from_slice(b"a\nb\nc"));
         let mut reader = BufferedReader::with_capacity(2, in_buf);
         assert_eq!(reader.read_line(), Ok("a\n".to_string()));
         assert_eq!(reader.read_line(), Ok("b\n".to_string()));
@@ -545,7 +545,7 @@ fn test_read_line() {
 
     #[test]
     fn test_lines() {
-        let in_buf = MemReader::new(Vec::from_slice(bytes!("a\nb\nc")));
+        let in_buf = MemReader::new(Vec::from_slice(b"a\nb\nc"));
         let mut reader = BufferedReader::with_capacity(2, in_buf);
         let mut it = reader.lines();
         assert_eq!(it.next(), Some(Ok("a\n".to_string())));
index 20187a6dcde6b53479178e356ea2fb03c5a0f8eb..a801dd0e7cb35cd39cf7966862ad3185859c1960 100644 (file)
@@ -35,7 +35,7 @@
 
 // create the file, whether it exists or not
 let mut file = File::create(&path);
-file.write(bytes!("foobar"));
+file.write(b"foobar");
 # drop(file);
 
 // open the file in read-only mode
@@ -186,7 +186,7 @@ pub fn open(path: &Path) -> IoResult<File> {
     /// use std::io::File;
     ///
     /// let mut f = File::create(&Path::new("foo.txt"));
-    /// f.write(bytes!("This is a sample file"));
+    /// f.write(b"This is a sample file");
     /// # drop(f);
     /// # ::std::io::fs::unlink(&Path::new("foo.txt"));
     /// ```
@@ -1141,7 +1141,7 @@ pub fn tmpdir() -> TempDir {
     iotest!(fn file_test_fileinfo_check_exists_before_and_after_file_creation() {
         let tmpdir = tmpdir();
         let file = &tmpdir.join("fileinfo_check_exists_b_and_a.txt");
-        check!(File::create(file).write(bytes!("foo")));
+        check!(File::create(file).write(b"foo"));
         assert!(file.exists());
         check!(unlink(file));
         assert!(!file.exists());
@@ -1253,7 +1253,7 @@ pub fn tmpdir() -> TempDir {
         let canary = d2.join("do_not_delete");
         check!(mkdir_recursive(&dtt, io::UserRWX));
         check!(mkdir_recursive(&d2, io::UserRWX));
-        check!(File::create(&canary).write(bytes!("foo")));
+        check!(File::create(&canary).write(b"foo"));
         check!(symlink(&d2, &dt.join("d2")));
         check!(rmdir_recursive(&d1));
 
@@ -1314,10 +1314,10 @@ pub fn tmpdir() -> TempDir {
         let input = tmpdir.join("in.txt");
         let out = tmpdir.join("out.txt");
 
-        check!(File::create(&input).write(bytes!("hello")));
+        check!(File::create(&input).write(b"hello"));
         check!(copy(&input, &out));
         let contents = check!(File::open(&out).read_to_end());
-        assert_eq!(contents.as_slice(), bytes!("hello"));
+        assert_eq!(contents.as_slice(), b"hello");
 
         assert_eq!(check!(input.stat()).perm, check!(out.stat()).perm);
     })
@@ -1342,7 +1342,7 @@ pub fn tmpdir() -> TempDir {
         check!(copy(&input, &output));
 
         assert_eq!(check!(File::open(&output).read_to_end()),
-                   (Vec::from_slice(bytes!("foo"))));
+                   (Vec::from_slice(b"foo")));
     })
 
     iotest!(fn copy_file_src_dir() {
@@ -1383,7 +1383,7 @@ pub fn tmpdir() -> TempDir {
         }
         assert_eq!(check!(stat(&out)).size, check!(stat(&input)).size);
         assert_eq!(check!(File::open(&out).read_to_end()),
-                   (Vec::from_slice(bytes!("foobar"))));
+                   (Vec::from_slice(b"foobar")));
     })
 
     #[cfg(not(windows))] // apparently windows doesn't like symlinks
@@ -1418,7 +1418,7 @@ pub fn tmpdir() -> TempDir {
         assert_eq!(check!(stat(&out)).size, check!(stat(&input)).size);
         assert_eq!(check!(stat(&out)).size, check!(input.stat()).size);
         assert_eq!(check!(File::open(&out).read_to_end()),
-                   (Vec::from_slice(bytes!("foobar"))));
+                   (Vec::from_slice(b"foobar")));
 
         // can't link to yourself
         match link(&input, &input) {
@@ -1456,7 +1456,7 @@ pub fn tmpdir() -> TempDir {
         let mut file = check!(File::open_mode(&path, io::Open, io::ReadWrite));
         check!(file.fsync());
         check!(file.datasync());
-        check!(file.write(bytes!("foo")));
+        check!(file.write(b"foo"));
         check!(file.fsync());
         check!(file.datasync());
         drop(file);
@@ -1467,29 +1467,29 @@ pub fn tmpdir() -> TempDir {
         let path = tmpdir.join("in.txt");
 
         let mut file = check!(File::open_mode(&path, io::Open, io::ReadWrite));
-        check!(file.write(bytes!("foo")));
+        check!(file.write(b"foo"));
         check!(file.fsync());
 
         // Do some simple things with truncation
         assert_eq!(check!(file.stat()).size, 3);
         check!(file.truncate(10));
         assert_eq!(check!(file.stat()).size, 10);
-        check!(file.write(bytes!("bar")));
+        check!(file.write(b"bar"));
         check!(file.fsync());
         assert_eq!(check!(file.stat()).size, 10);
         assert_eq!(check!(File::open(&path).read_to_end()),
-                   (Vec::from_slice(bytes!("foobar", 0, 0, 0, 0))));
+                   (Vec::from_slice(b"foobar\0\0\0\0")));
 
         // Truncate to a smaller length, don't seek, and then write something.
         // Ensure that the intermediate zeroes are all filled in (we're seeked
         // past the end of the file).
         check!(file.truncate(2));
         assert_eq!(check!(file.stat()).size, 2);
-        check!(file.write(bytes!("wut")));
+        check!(file.write(b"wut"));
         check!(file.fsync());
         assert_eq!(check!(file.stat()).size, 9);
         assert_eq!(check!(File::open(&path).read_to_end()),
-                   (Vec::from_slice(bytes!("fo", 0, 0, 0, 0, "wut"))));
+                   (Vec::from_slice(b"fo\0\0\0\0wut")));
         drop(file);
     })
 
index 71a967bb8dc5f41037fc64910f756fa1bb274e70..5eca5361835e36e7295f5d5f66f6ffde1df300c8 100644 (file)
@@ -474,7 +474,7 @@ fn test_buf_reader() {
 
     #[test]
     fn test_read_char() {
-        let b = bytes!("Việt");
+        let b = b"Vi\xE1\xBB\x87t";
         let mut r = BufReader::new(b);
         assert_eq!(r.read_char(), Ok('V'));
         assert_eq!(r.read_char(), Ok('i'));
@@ -485,7 +485,7 @@ fn test_read_char() {
 
     #[test]
     fn test_read_bad_char() {
-        let b = bytes!(0x80);
+        let b = b"\x80";
         let mut r = BufReader::new(b);
         assert!(r.read_char().is_err());
     }
index a7f84899a622e1703858bab178a2fe3059a6bdbc..d9755cdce1a4fbf1099fac36b541f4fef3f9ca57 100644 (file)
@@ -50,7 +50,7 @@
     use std::io::File;
 
     let mut file = File::create(&Path::new("message.txt"));
-    file.write(bytes!("hello, file!\n"));
+    file.write(b"hello, file!\n");
     # drop(file);
     # ::std::io::fs::unlink(&Path::new("message.txt"));
     ```
@@ -90,7 +90,7 @@
     # // just stop it running (#11576)
     # if false {
     let mut socket = TcpStream::connect("127.0.0.1", 8080).unwrap();
-    socket.write(bytes!("GET / HTTP/1.0\n\n"));
+    socket.write(b"GET / HTTP/1.0\n\n");
     let response = socket.read_to_end();
     # }
     ```
@@ -151,7 +151,7 @@ fn handle_client(mut stream: TcpStream) {
   to be 'unwrapped' before use.
 
 These features combine in the API to allow for expressions like
-`File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n"))`
+`File::create(&Path::new("diary.txt")).write(b"Met a girl.\n")`
 without having to worry about whether "diary.txt" exists or whether
 the write succeeds. As written, if either `new` or `write_line`
 encounters an error then the result of the entire expression will
@@ -163,7 +163,7 @@ fn handle_client(mut stream: TcpStream) {
 # #![allow(unused_must_use)]
 use std::io::File;
 
-match File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n")) {
+match File::create(&Path::new("diary.txt")).write(b"Met a girl.\n") {
     Ok(()) => (), // succeeded
     Err(e) => println!("failed to write to my diary: {}", e),
 }
@@ -1839,55 +1839,55 @@ fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
 
     #[test]
     fn test_read_at_least() {
-        let mut r = BadReader::new(MemReader::new(Vec::from_slice(bytes!("hello, world!"))),
+        let mut r = BadReader::new(MemReader::new(Vec::from_slice(b"hello, world!")),
                                    Vec::from_slice([GoodBehavior(uint::MAX)]));
         let mut buf = [0u8, ..5];
         assert!(r.read_at_least(1, buf).unwrap() >= 1);
         assert!(r.read_exact(5).unwrap().len() == 5); // read_exact uses read_at_least
         assert!(r.read_at_least(0, buf).is_ok());
 
-        let mut r = BadReader::new(MemReader::new(Vec::from_slice(bytes!("hello, world!"))),
+        let mut r = BadReader::new(MemReader::new(Vec::from_slice(b"hello, world!")),
                                    Vec::from_slice([BadBehavior(50), GoodBehavior(uint::MAX)]));
         assert!(r.read_at_least(1, buf).unwrap() >= 1);
 
-        let mut r = BadReader::new(MemReader::new(Vec::from_slice(bytes!("hello, world!"))),
+        let mut r = BadReader::new(MemReader::new(Vec::from_slice(b"hello, world!")),
                                    Vec::from_slice([BadBehavior(1), GoodBehavior(1),
                                                     BadBehavior(50), GoodBehavior(uint::MAX)]));
         assert!(r.read_at_least(1, buf).unwrap() >= 1);
         assert!(r.read_at_least(1, buf).unwrap() >= 1);
 
-        let mut r = BadReader::new(MemReader::new(Vec::from_slice(bytes!("hello, world!"))),
+        let mut r = BadReader::new(MemReader::new(Vec::from_slice(b"hello, world!")),
                                    Vec::from_slice([BadBehavior(uint::MAX)]));
         assert_eq!(r.read_at_least(1, buf).unwrap_err().kind, NoProgress);
 
-        let mut r = MemReader::new(Vec::from_slice(bytes!("hello, world!")));
+        let mut r = MemReader::new(Vec::from_slice(b"hello, world!"));
         assert_eq!(r.read_at_least(5, buf).unwrap(), 5);
         assert_eq!(r.read_at_least(6, buf).unwrap_err().kind, InvalidInput);
     }
 
     #[test]
     fn test_push_at_least() {
-        let mut r = BadReader::new(MemReader::new(Vec::from_slice(bytes!("hello, world!"))),
+        let mut r = BadReader::new(MemReader::new(Vec::from_slice(b"hello, world!")),
                                    Vec::from_slice([GoodBehavior(uint::MAX)]));
         let mut buf = Vec::new();
         assert!(r.push_at_least(1, 5, &mut buf).unwrap() >= 1);
         assert!(r.push_at_least(0, 5, &mut buf).is_ok());
 
-        let mut r = BadReader::new(MemReader::new(Vec::from_slice(bytes!("hello, world!"))),
+        let mut r = BadReader::new(MemReader::new(Vec::from_slice(b"hello, world!")),
                                    Vec::from_slice([BadBehavior(50), GoodBehavior(uint::MAX)]));
         assert!(r.push_at_least(1, 5, &mut buf).unwrap() >= 1);
 
-        let mut r = BadReader::new(MemReader::new(Vec::from_slice(bytes!("hello, world!"))),
+        let mut r = BadReader::new(MemReader::new(Vec::from_slice(b"hello, world!")),
                                    Vec::from_slice([BadBehavior(1), GoodBehavior(1),
                                                     BadBehavior(50), GoodBehavior(uint::MAX)]));
         assert!(r.push_at_least(1, 5, &mut buf).unwrap() >= 1);
         assert!(r.push_at_least(1, 5, &mut buf).unwrap() >= 1);
 
-        let mut r = BadReader::new(MemReader::new(Vec::from_slice(bytes!("hello, world!"))),
+        let mut r = BadReader::new(MemReader::new(Vec::from_slice(b"hello, world!")),
                                    Vec::from_slice([BadBehavior(uint::MAX)]));
         assert_eq!(r.push_at_least(1, 5, &mut buf).unwrap_err().kind, NoProgress);
 
-        let mut r = MemReader::new(Vec::from_slice(bytes!("hello, world!")));
+        let mut r = MemReader::new(Vec::from_slice(b"hello, world!"));
         assert_eq!(r.push_at_least(5, 1, &mut buf).unwrap_err().kind, InvalidInput);
     }
 }
index 84d388c113630ecba3187a4609c5e8785ae5d6f7..a968f41a91563ce9c7d7a66bf7a551fa9db94f13 100644 (file)
@@ -52,7 +52,7 @@ impl PipeStream {
     ///
     /// fn main() {
     ///     let mut pipe = PipeStream::open(libc::STDERR_FILENO);
-    ///     pipe.write(bytes!("Hello, stderr!"));
+    ///     pipe.write(b"Hello, stderr!");
     /// }
     /// ```
     pub fn open(fd: libc::c_int) -> IoResult<PipeStream> {
index c989dcc3d2945eb21577a44c1c0b581e809f0d47..e5a64f785ce9640643911ef9c55fb8a76f44b77c 100644 (file)
@@ -22,7 +22,7 @@
 use std::io;
 
 let mut out = io::stdout();
-out.write(bytes!("Hello, world!"));
+out.write(b"Hello, world!");
 ```
 
 */
index 602a2240f39084a5438f3a3bfb6b8e60e236dc5d..7301f9b08e9dcef30ede009c9db3b77d84adec98 100644 (file)
@@ -22,7 +22,7 @@
 
 pub use core::num::{Num, div_rem, Zero, zero, One, one};
 pub use core::num::{Signed, abs, abs_sub, signum};
-pub use core::num::{Unsigned, pow, Bounded, Bitwise};
+pub use core::num::{Unsigned, pow, Bounded};
 pub use core::num::{Primitive, Int, Saturating};
 pub use core::num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv};
 pub use core::num::{cast, FromPrimitive, NumCast, ToPrimitive};
index 7d15893af241e865136b1194dca2536d8cff462a..e55dc165895164a5d07dd29f7137d1c82d878a37 100644 (file)
@@ -219,7 +219,7 @@ fn filestem<'a>(&'a self) -> Option<&'a [u8]> {
                 let dot = '.' as u8;
                 match name.rposition_elem(&dot) {
                     None | Some(0) => name,
-                    Some(1) if name == bytes!("..") => name,
+                    Some(1) if name == b".." => name,
                     Some(pos) => name.slice_to(pos)
                 }
             })
@@ -242,7 +242,7 @@ fn extension<'a>(&'a self) -> Option<&'a [u8]> {
                 let dot = '.' as u8;
                 match name.rposition_elem(&dot) {
                     None | Some(0) => None,
-                    Some(1) if name == bytes!("..") => None,
+                    Some(1) if name == b".." => None,
                     Some(pos) => Some(name.slice_from(pos+1))
                 }
             }
index 494428de3a5c48aadaf85dc7563208bac908cae4..d98cfb7d8eece0c35396db2b1a5dd2cb48614a6e 100644 (file)
@@ -142,7 +142,7 @@ unsafe fn new_unchecked<T: BytesContainer>(path: T) -> Path {
     unsafe fn set_filename_unchecked<T: BytesContainer>(&mut self, filename: T) {
         let filename = filename.container_as_bytes();
         match self.sepidx {
-            None if bytes!("..") == self.repr.as_slice() => {
+            None if b".." == self.repr.as_slice() => {
                 let mut v = Vec::with_capacity(3 + filename.len());
                 v.push_all(dot_dot_static);
                 v.push(SEP_BYTE);
@@ -153,7 +153,7 @@ unsafe fn set_filename_unchecked<T: BytesContainer>(&mut self, filename: T) {
             None => {
                 self.repr = Path::normalize(filename);
             }
-            Some(idx) if self.repr.slice_from(idx+1) == bytes!("..") => {
+            Some(idx) if self.repr.slice_from(idx+1) == b".." => {
                 let mut v = Vec::with_capacity(self.repr.len() + 1 + filename.len());
                 v.push_all(self.repr.as_slice());
                 v.push(SEP_BYTE);
@@ -202,20 +202,20 @@ fn into_vec(self) -> Vec<u8> {
 
     fn dirname<'a>(&'a self) -> &'a [u8] {
         match self.sepidx {
-            None if bytes!("..") == self.repr.as_slice() => self.repr.as_slice(),
+            None if b".." == self.repr.as_slice() => self.repr.as_slice(),
             None => dot_static,
             Some(0) => self.repr.slice_to(1),
-            Some(idx) if self.repr.slice_from(idx+1) == bytes!("..") => self.repr.as_slice(),
+            Some(idx) if self.repr.slice_from(idx+1) == b".." => self.repr.as_slice(),
             Some(idx) => self.repr.slice_to(idx)
         }
     }
 
     fn filename<'a>(&'a self) -> Option<&'a [u8]> {
         match self.sepidx {
-            None if bytes!(".") == self.repr.as_slice() ||
-                bytes!("..") == self.repr.as_slice() => None,
+            None if b"." == self.repr.as_slice() ||
+                b".." == self.repr.as_slice() => None,
             None => Some(self.repr.as_slice()),
-            Some(idx) if self.repr.slice_from(idx+1) == bytes!("..") => None,
+            Some(idx) if self.repr.slice_from(idx+1) == b".." => None,
             Some(0) if self.repr.slice_from(1).is_empty() => None,
             Some(idx) => Some(self.repr.slice_from(idx+1))
         }
@@ -223,13 +223,13 @@ fn filename<'a>(&'a self) -> Option<&'a [u8]> {
 
     fn pop(&mut self) -> bool {
         match self.sepidx {
-            None if bytes!(".") == self.repr.as_slice() => false,
+            None if b"." == self.repr.as_slice() => false,
             None => {
                 self.repr = vec!['.' as u8];
                 self.sepidx = None;
                 true
             }
-            Some(0) if bytes!("/") == self.repr.as_slice() => false,
+            Some(0) if b"/" == self.repr.as_slice() => false,
             Some(idx) => {
                 if idx == 0 {
                     self.repr.truncate(idx+1);
@@ -261,19 +261,19 @@ fn is_ancestor_of(&self, other: &Path) -> bool {
         } else {
             let mut ita = self.components();
             let mut itb = other.components();
-            if bytes!(".") == self.repr.as_slice() {
+            if b"." == self.repr.as_slice() {
                 return match itb.next() {
                     None => true,
-                    Some(b) => b != bytes!("..")
+                    Some(b) => b != b".."
                 };
             }
             loop {
                 match (ita.next(), itb.next()) {
                     (None, _) => break,
                     (Some(a), Some(b)) if a == b => { continue },
-                    (Some(a), _) if a == bytes!("..") => {
+                    (Some(a), _) if a == b".." => {
                         // if ita contains only .. components, it's an ancestor
-                        return ita.all(|x| x == bytes!(".."));
+                        return ita.all(|x| x == b"..");
                     }
                     _ => return false
                 }
@@ -303,8 +303,8 @@ fn path_relative_from(&self, base: &Path) -> Option<Path> {
                     }
                     (None, _) => comps.push(dot_dot_static),
                     (Some(a), Some(b)) if comps.is_empty() && a == b => (),
-                    (Some(a), Some(b)) if b == bytes!(".") => comps.push(a),
-                    (Some(_), Some(b)) if b == bytes!("..") => return None,
+                    (Some(a), Some(b)) if b == b"." => comps.push(a),
+                    (Some(_), Some(b)) if b == b".." => return None,
                     (Some(a), Some(_)) => {
                         comps.push(dot_dot_static);
                         for _ in itb {
@@ -425,8 +425,8 @@ fn normalize_helper<'a>(v: &'a [u8], is_abs: bool) -> Option<Vec<&'a [u8]>> {
     let mut changed = false;
     for comp in v.split(is_sep_byte) {
         if comp.is_empty() { changed = true }
-        else if comp == bytes!(".") { changed = true }
-        else if comp == bytes!("..") {
+        else if comp == b"." { changed = true }
+        else if comp == b".." {
             if is_abs && comps.is_empty() { changed = true }
             else if comps.len() == n_up { comps.push(dot_dot_static); n_up += 1 }
             else { comps.pop().unwrap(); changed = true }
@@ -434,7 +434,7 @@ fn normalize_helper<'a>(v: &'a [u8], is_abs: bool) -> Option<Vec<&'a [u8]>> {
     }
     if changed {
         if comps.is_empty() && !is_abs {
-            if v == bytes!(".") {
+            if v == b"." {
                 return None;
             }
             comps.push(dot_static);
@@ -445,8 +445,8 @@ fn normalize_helper<'a>(v: &'a [u8], is_abs: bool) -> Option<Vec<&'a [u8]>> {
     }
 }
 
-static dot_static: &'static [u8] = bytes!(".");
-static dot_dot_static: &'static [u8] = bytes!("..");
+static dot_static: &'static [u8] = b".";
+static dot_dot_static: &'static [u8] = b"..";
 
 #[cfg(test)]
 mod tests {
@@ -470,24 +470,15 @@ macro_rules! t(
         )
     )
 
-    macro_rules! b(
-        ($($arg:expr),+) => (
-            {
-                static the_bytes: &'static [u8] = bytes!($($arg),+);
-                the_bytes
-            }
-        )
-    )
-
     #[test]
     fn test_paths() {
         let empty: &[u8] = [];
-        t!(v: Path::new(empty), b!("."));
-        t!(v: Path::new(b!("/")), b!("/"));
-        t!(v: Path::new(b!("a/b/c")), b!("a/b/c"));
-        t!(v: Path::new(b!("a/b/c", 0xff)), b!("a/b/c", 0xff));
-        t!(v: Path::new(b!(0xff, "/../foo", 0x80)), b!("foo", 0x80));
-        let p = Path::new(b!("a/b/c", 0xff));
+        t!(v: Path::new(empty), b".");
+        t!(v: Path::new(b"/"), b"/");
+        t!(v: Path::new(b"a/b/c"), b"a/b/c");
+        t!(v: Path::new(b"a/b/c\xFF"), b"a/b/c\xFF");
+        t!(v: Path::new(b"\xFF/../foo\x80"), b"foo\x80");
+        let p = Path::new(b"a/b/c\xFF");
         assert!(p.as_str() == None);
 
         t!(s: Path::new(""), ".");
@@ -513,18 +504,18 @@ fn test_paths() {
         t!(s: Path::new("foo/../../.."), "../..");
         t!(s: Path::new("foo/../../bar"), "../bar");
 
-        assert_eq!(Path::new(b!("foo/bar")).into_vec().as_slice(), b!("foo/bar"));
-        assert_eq!(Path::new(b!("/foo/../../bar")).into_vec().as_slice(),
-                   b!("/bar"));
+        assert_eq!(Path::new(b"foo/bar").into_vec().as_slice(), b"foo/bar");
+        assert_eq!(Path::new(b"/foo/../../bar").into_vec().as_slice(),
+                   b"/bar");
 
-        let p = Path::new(b!("foo/bar", 0x80));
+        let p = Path::new(b"foo/bar\x80");
         assert!(p.as_str() == None);
     }
 
     #[test]
     fn test_opt_paths() {
-        assert!(Path::new_opt(b!("foo/bar", 0)) == None);
-        t!(v: Path::new_opt(b!("foo/bar")).unwrap(), b!("foo/bar"));
+        assert!(Path::new_opt(b"foo/bar\0") == None);
+        t!(v: Path::new_opt(b"foo/bar").unwrap(), b"foo/bar");
         assert!(Path::new_opt("foo/bar\0") == None);
         t!(s: Path::new_opt("foo/bar").unwrap(), "foo/bar");
     }
@@ -533,17 +524,17 @@ fn test_opt_paths() {
     fn test_null_byte() {
         use task;
         let result = task::try(proc() {
-            Path::new(b!("foo/bar", 0))
+            Path::new(b"foo/bar\0")
         });
         assert!(result.is_err());
 
         let result = task::try(proc() {
-            Path::new("test").set_filename(b!("f", 0, "o"))
+            Path::new("test").set_filename(b"f\0o")
         });
         assert!(result.is_err());
 
         let result = task::try(proc() {
-            Path::new("test").push(b!("f", 0, "o"));
+            Path::new("test").push(b"f\0o");
         });
         assert!(result.is_err());
     }
@@ -559,11 +550,11 @@ macro_rules! t(
             )
         )
         t!("foo", display, "foo");
-        t!(b!("foo", 0x80), display, "foo\uFFFD");
-        t!(b!("foo", 0xff, "bar"), display, "foo\uFFFDbar");
-        t!(b!("foo", 0xff, "/bar"), filename_display, "bar");
-        t!(b!("foo/", 0xff, "bar"), filename_display, "\uFFFDbar");
-        t!(b!("/"), filename_display, "");
+        t!(b"foo\x80", display, "foo\uFFFD");
+        t!(b"foo\xFFbar", display, "foo\uFFFDbar");
+        t!(b"foo\xFF/bar", filename_display, "bar");
+        t!(b"foo/\xFFbar", filename_display, "\uFFFDbar");
+        t!(b"/", filename_display, "");
 
         macro_rules! t(
             ($path:expr, $exp:expr) => (
@@ -583,11 +574,11 @@ macro_rules! t(
         )
 
         t!("foo", "foo");
-        t!(b!("foo", 0x80), "foo\uFFFD");
-        t!(b!("foo", 0xff, "bar"), "foo\uFFFDbar");
-        t!(b!("foo", 0xff, "/bar"), "bar", filename);
-        t!(b!("foo/", 0xff, "bar"), "\uFFFDbar", filename);
-        t!(b!("/"), "", filename);
+        t!(b"foo\x80", "foo\uFFFD");
+        t!(b"foo\xFFbar", "foo\uFFFDbar");
+        t!(b"foo\xFF/bar", "bar", filename);
+        t!(b"foo/\xFFbar", "\uFFFDbar", filename);
+        t!(b"/", "", filename);
     }
 
     #[test]
@@ -604,13 +595,13 @@ macro_rules! t(
             )
         )
 
-        t!(b!("foo"), "foo", "foo");
-        t!(b!("foo/bar"), "foo/bar", "bar");
-        t!(b!("/"), "/", "");
-        t!(b!("foo", 0xff), "foo\uFFFD", "foo\uFFFD");
-        t!(b!("foo", 0xff, "/bar"), "foo\uFFFD/bar", "bar");
-        t!(b!("foo/", 0xff, "bar"), "foo/\uFFFDbar", "\uFFFDbar");
-        t!(b!(0xff, "foo/bar", 0xff), "\uFFFDfoo/bar\uFFFD", "bar\uFFFD");
+        t!(b"foo", "foo", "foo");
+        t!(b"foo/bar", "foo/bar", "bar");
+        t!(b"/", "/", "");
+        t!(b"foo\xFF", "foo\uFFFD", "foo\uFFFD");
+        t!(b"foo\xFF/bar", "foo\uFFFD/bar", "bar");
+        t!(b"foo/\xFFbar", "foo/\uFFFDbar", "\uFFFDbar");
+        t!(b"\xFFfoo/bar\xFF", "\uFFFDfoo/bar\uFFFD", "bar\uFFFD");
     }
 
     #[test]
@@ -638,9 +629,9 @@ macro_rules! t(
             );
         )
 
-        t!(v: b!("a/b/c"), filename, Some(b!("c")));
-        t!(v: b!("a/b/c", 0xff), filename, Some(b!("c", 0xff)));
-        t!(v: b!("a/b", 0xff, "/c"), filename, Some(b!("c")));
+        t!(v: b"a/b/c", filename, Some(b"c"));
+        t!(v: b"a/b/c\xFF", filename, Some(b"c\xFF"));
+        t!(v: b"a/b\xFF/c", filename, Some(b"c"));
         t!(s: "a/b/c", filename, Some("c"), opt);
         t!(s: "/a/b/c", filename, Some("c"), opt);
         t!(s: "a", filename, Some("a"), opt);
@@ -650,9 +641,9 @@ macro_rules! t(
         t!(s: "..", filename, None, opt);
         t!(s: "../..", filename, None, opt);
 
-        t!(v: b!("a/b/c"), dirname, b!("a/b"));
-        t!(v: b!("a/b/c", 0xff), dirname, b!("a/b"));
-        t!(v: b!("a/b", 0xff, "/c"), dirname, b!("a/b", 0xff));
+        t!(v: b"a/b/c", dirname, b"a/b");
+        t!(v: b"a/b/c\xFF", dirname, b"a/b");
+        t!(v: b"a/b\xFF/c", dirname, b"a/b\xFF");
         t!(s: "a/b/c", dirname, "a/b");
         t!(s: "/a/b/c", dirname, "/a/b");
         t!(s: "a", dirname, ".");
@@ -662,9 +653,9 @@ macro_rules! t(
         t!(s: "..", dirname, "..");
         t!(s: "../..", dirname, "../..");
 
-        t!(v: b!("hi/there.txt"), filestem, Some(b!("there")));
-        t!(v: b!("hi/there", 0x80, ".txt"), filestem, Some(b!("there", 0x80)));
-        t!(v: b!("hi/there.t", 0x80, "xt"), filestem, Some(b!("there")));
+        t!(v: b"hi/there.txt", filestem, Some(b"there"));
+        t!(v: b"hi/there\x80.txt", filestem, Some(b"there\x80"));
+        t!(v: b"hi/there.t\x80xt", filestem, Some(b"there"));
         t!(s: "hi/there.txt", filestem, Some("there"), opt);
         t!(s: "hi/there", filestem, Some("there"), opt);
         t!(s: "there.txt", filestem, Some("there"), opt);
@@ -678,11 +669,11 @@ macro_rules! t(
         t!(s: "..", filestem, None, opt);
         t!(s: "../..", filestem, None, opt);
 
-        t!(v: b!("hi/there.txt"), extension, Some(b!("txt")));
-        t!(v: b!("hi/there", 0x80, ".txt"), extension, Some(b!("txt")));
-        t!(v: b!("hi/there.t", 0x80, "xt"), extension, Some(b!("t", 0x80, "xt")));
-        t!(v: b!("hi/there"), extension, None);
-        t!(v: b!("hi/there", 0x80), extension, None);
+        t!(v: b"hi/there.txt", extension, Some(b"txt"));
+        t!(v: b"hi/there\x80.txt", extension, Some(b"txt"));
+        t!(v: b"hi/there.t\x80xt", extension, Some(b"t\x80xt"));
+        t!(v: b"hi/there", extension, None);
+        t!(v: b"hi/there\x80", extension, None);
         t!(s: "hi/there.txt", extension, Some("txt"), opt);
         t!(s: "hi/there", extension, None, opt);
         t!(s: "there.txt", extension, Some("txt"), opt);
@@ -762,9 +753,9 @@ macro_rules! t(
         t!(s: "a/b/c", ["d", "/e"], "/e");
         t!(s: "a/b/c", ["d", "/e", "f"], "/e/f");
         t!(s: "a/b/c", ["d".to_string(), "e".to_string()], "a/b/c/d/e");
-        t!(v: b!("a/b/c"), [b!("d"), b!("e")], b!("a/b/c/d/e"));
-        t!(v: b!("a/b/c"), [b!("d"), b!("/e"), b!("f")], b!("/e/f"));
-        t!(v: b!("a/b/c"), [Vec::from_slice(b!("d")), Vec::from_slice(b!("e"))], b!("a/b/c/d/e"));
+        t!(v: b"a/b/c", [b"d", b"e"], b"a/b/c/d/e");
+        t!(v: b"a/b/c", [b"d", b"/e", b"f"], b"/e/f");
+        t!(v: b"a/b/c", [Vec::from_slice(b"d"), Vec::from_slice(b"e")], b"a/b/c/d/e");
     }
 
     #[test]
@@ -778,25 +769,25 @@ macro_rules! t(
                     assert!(result == $right);
                 }
             );
-            (v: [$($path:expr),+], [$($left:expr),+], $right:expr) => (
+            (b: $path:expr, $left:expr, $right:expr) => (
                 {
-                    let mut p = Path::new(b!($($path),+));
+                    let mut p = Path::new($path);
                     let result = p.pop();
-                    assert!(p.as_vec() == b!($($left),+));
+                    assert!(p.as_vec() == $left);
                     assert!(result == $right);
                 }
             )
         )
 
-        t!(v: ["a/b/c"], ["a/b"], true);
-        t!(v: ["a"], ["."], true);
-        t!(v: ["."], ["."], false);
-        t!(v: ["/a"], ["/"], true);
-        t!(v: ["/"], ["/"], false);
-        t!(v: ["a/b/c", 0x80], ["a/b"], true);
-        t!(v: ["a/b", 0x80, "/c"], ["a/b", 0x80], true);
-        t!(v: [0xff], ["."], true);
-        t!(v: ["/", 0xff], ["/"], true);
+        t!(b: b"a/b/c", b"a/b", true);
+        t!(b: b"a", b".", true);
+        t!(b: b".", b".", false);
+        t!(b: b"/a", b"/", true);
+        t!(b: b"/", b"/", false);
+        t!(b: b"a/b/c\x80", b"a/b", true);
+        t!(b: b"a/b\x80/c", b"a/b\x80", true);
+        t!(b: b"\xFF", b".", true);
+        t!(b: b"/\xFF", b"/", true);
         t!(s: "a/b/c", "a/b", true);
         t!(s: "a", ".", true);
         t!(s: ".", ".", false);
@@ -806,15 +797,15 @@ macro_rules! t(
 
     #[test]
     fn test_root_path() {
-        assert!(Path::new(b!("a/b/c")).root_path() == None);
-        assert!(Path::new(b!("/a/b/c")).root_path() == Some(Path::new("/")));
+        assert!(Path::new(b"a/b/c").root_path() == None);
+        assert!(Path::new(b"/a/b/c").root_path() == Some(Path::new("/")));
     }
 
     #[test]
     fn test_join() {
-        t!(v: Path::new(b!("a/b/c")).join(b!("..")), b!("a/b"));
-        t!(v: Path::new(b!("/a/b/c")).join(b!("d")), b!("/a/b/c/d"));
-        t!(v: Path::new(b!("a/", 0x80, "/c")).join(b!(0xff)), b!("a/", 0x80, "/c/", 0xff));
+        t!(v: Path::new(b"a/b/c").join(b".."), b"a/b");
+        t!(v: Path::new(b"/a/b/c").join(b"d"), b"/a/b/c/d");
+        t!(v: Path::new(b"a/\x80/c").join(b"\xFF"), b"a/\x80/c/\xFF");
         t!(s: Path::new("a/b/c").join(".."), "a/b");
         t!(s: Path::new("/a/b/c").join("d"), "/a/b/c/d");
         t!(s: Path::new("a/b").join("c/d"), "a/b/c/d");
@@ -867,18 +858,18 @@ macro_rules! t(
         t!(s: "a/b/c", ["..", "d"], "a/b/d");
         t!(s: "a/b/c", ["d", "/e", "f"], "/e/f");
         t!(s: "a/b/c", ["d".to_string(), "e".to_string()], "a/b/c/d/e");
-        t!(v: b!("a/b/c"), [b!("d"), b!("e")], b!("a/b/c/d/e"));
-        t!(v: b!("a/b/c"), [Vec::from_slice(b!("d")), Vec::from_slice(b!("e"))], b!("a/b/c/d/e"));
+        t!(v: b"a/b/c", [b"d", b"e"], b"a/b/c/d/e");
+        t!(v: b"a/b/c", [Vec::from_slice(b"d"), Vec::from_slice(b"e")], b"a/b/c/d/e");
     }
 
     #[test]
     fn test_with_helpers() {
         let empty: &[u8] = [];
 
-        t!(v: Path::new(b!("a/b/c")).with_filename(b!("d")), b!("a/b/d"));
-        t!(v: Path::new(b!("a/b/c", 0xff)).with_filename(b!(0x80)), b!("a/b/", 0x80));
-        t!(v: Path::new(b!("/", 0xff, "/foo")).with_filename(b!(0xcd)),
-              b!("/", 0xff, "/", 0xcd));
+        t!(v: Path::new(b"a/b/c").with_filename(b"d"), b"a/b/d");
+        t!(v: Path::new(b"a/b/c\xFF").with_filename(b"\x80"), b"a/b/\x80");
+        t!(v: Path::new(b"/\xFF/foo").with_filename(b"\xCD"),
+              b"/\xFF/\xCD");
         t!(s: Path::new("a/b/c").with_filename("d"), "a/b/d");
         t!(s: Path::new(".").with_filename("foo"), "foo");
         t!(s: Path::new("/a/b/c").with_filename("d"), "/a/b/d");
@@ -899,13 +890,13 @@ fn test_with_helpers() {
         t!(s: Path::new("..").with_filename(""), "..");
         t!(s: Path::new("../..").with_filename(""), "../..");
 
-        t!(v: Path::new(b!("hi/there", 0x80, ".txt")).with_extension(b!("exe")),
-              b!("hi/there", 0x80, ".exe"));
-        t!(v: Path::new(b!("hi/there.txt", 0x80)).with_extension(b!(0xff)),
-              b!("hi/there.", 0xff));
-        t!(v: Path::new(b!("hi/there", 0x80)).with_extension(b!(0xff)),
-              b!("hi/there", 0x80, ".", 0xff));
-        t!(v: Path::new(b!("hi/there.", 0xff)).with_extension(empty), b!("hi/there"));
+        t!(v: Path::new(b"hi/there\x80.txt").with_extension(b"exe"),
+              b"hi/there\x80.exe");
+        t!(v: Path::new(b"hi/there.txt\x80").with_extension(b"\xFF"),
+              b"hi/there.\xFF");
+        t!(v: Path::new(b"hi/there\x80").with_extension(b"\xFF"),
+              b"hi/there\x80.\xFF");
+        t!(v: Path::new(b"hi/there.\xFF").with_extension(empty), b"hi/there");
         t!(s: Path::new("hi/there.txt").with_extension("exe"), "hi/there.exe");
         t!(s: Path::new("hi/there.txt").with_extension(""), "hi/there");
         t!(s: Path::new("hi/there.txt").with_extension("."), "hi/there..");
@@ -947,17 +938,17 @@ macro_rules! t(
             )
         )
 
-        t!(v: b!("a/b/c"), set_filename, with_filename, b!("d"));
-        t!(v: b!("/"), set_filename, with_filename, b!("foo"));
-        t!(v: b!(0x80), set_filename, with_filename, b!(0xff));
+        t!(v: b"a/b/c", set_filename, with_filename, b"d");
+        t!(v: b"/", set_filename, with_filename, b"foo");
+        t!(v: b"\x80", set_filename, with_filename, b"\xFF");
         t!(s: "a/b/c", set_filename, with_filename, "d");
         t!(s: "/", set_filename, with_filename, "foo");
         t!(s: ".", set_filename, with_filename, "foo");
         t!(s: "a/b", set_filename, with_filename, "");
         t!(s: "a", set_filename, with_filename, "");
 
-        t!(v: b!("hi/there.txt"), set_extension, with_extension, b!("exe"));
-        t!(v: b!("hi/there.t", 0x80, "xt"), set_extension, with_extension, b!("exe", 0xff));
+        t!(v: b"hi/there.txt", set_extension, with_extension, b"exe");
+        t!(v: b"hi/there.t\x80xt", set_extension, with_extension, b"exe\xFF");
         t!(s: "hi/there.txt", set_extension, with_extension, "exe");
         t!(s: "hi/there.", set_extension, with_extension, "txt");
         t!(s: "hi/there", set_extension, with_extension, "txt");
@@ -1001,10 +992,10 @@ macro_rules! t(
             )
         )
 
-        t!(v: Path::new(b!("a/b/c")), Some(b!("c")), b!("a/b"), Some(b!("c")), None);
-        t!(v: Path::new(b!("a/b/", 0xff)), Some(b!(0xff)), b!("a/b"), Some(b!(0xff)), None);
-        t!(v: Path::new(b!("hi/there.", 0xff)), Some(b!("there.", 0xff)), b!("hi"),
-              Some(b!("there")), Some(b!(0xff)));
+        t!(v: Path::new(b"a/b/c"), Some(b"c"), b"a/b", Some(b"c"), None);
+        t!(v: Path::new(b"a/b/\xFF"), Some(b"\xFF"), b"a/b", Some(b"\xFF"), None);
+        t!(v: Path::new(b"hi/there.\xFF"), Some(b"there.\xFF"), b"hi",
+              Some(b"there"), Some(b"\xFF"));
         t!(s: Path::new("a/b/c"), Some("c"), Some("a/b"), Some("c"), None);
         t!(s: Path::new("."), None, Some("."), None, None);
         t!(s: Path::new("/"), None, Some("/"), None, None);
@@ -1018,16 +1009,16 @@ macro_rules! t(
         t!(s: Path::new("hi/.there"), Some(".there"), Some("hi"), Some(".there"), None);
         t!(s: Path::new("hi/..there"), Some("..there"), Some("hi"),
               Some("."), Some("there"));
-        t!(s: Path::new(b!("a/b/", 0xff)), None, Some("a/b"), None, None);
-        t!(s: Path::new(b!("a/b/", 0xff, ".txt")), None, Some("a/b"), None, Some("txt"));
-        t!(s: Path::new(b!("a/b/c.", 0x80)), None, Some("a/b"), Some("c"), None);
-        t!(s: Path::new(b!(0xff, "/b")), Some("b"), None, Some("b"), None);
+        t!(s: Path::new(b"a/b/\xFF"), None, Some("a/b"), None, None);
+        t!(s: Path::new(b"a/b/\xFF.txt"), None, Some("a/b"), None, Some("txt"));
+        t!(s: Path::new(b"a/b/c.\x80"), None, Some("a/b"), Some("c"), None);
+        t!(s: Path::new(b"\xFF/b"), Some("b"), None, Some("b"), None);
     }
 
     #[test]
     fn test_dir_path() {
-        t!(v: Path::new(b!("hi/there", 0x80)).dir_path(), b!("hi"));
-        t!(v: Path::new(b!("hi", 0xff, "/there")).dir_path(), b!("hi", 0xff));
+        t!(v: Path::new(b"hi/there\x80").dir_path(), b"hi");
+        t!(v: Path::new(b"hi\xFF/there").dir_path(), b"hi\xFF");
         t!(s: Path::new("hi/there").dir_path(), "hi");
         t!(s: Path::new("hi").dir_path(), ".");
         t!(s: Path::new("/hi").dir_path(), "/");
@@ -1125,9 +1116,9 @@ macro_rules! t(
         t!(s: "/a/b/c", "d/e/f", false);
         t!(s: "a/b/c", "a/b", false);
         t!(s: "a/b/c", "b", false);
-        t!(v: b!("a/b/c"), b!("b/c"), true);
-        t!(v: b!("a/b/", 0xff), b!(0xff), true);
-        t!(v: b!("a/b/", 0xff), b!("b/", 0xff), true);
+        t!(v: b"a/b/c", b"b/c", true);
+        t!(v: b"a/b/\xFF", b"\xFF", true);
+        t!(v: b"a/b/\xFF", b"b/\xFF", true);
     }
 
     #[test]
@@ -1192,11 +1183,11 @@ macro_rules! t(
                             comps, exps);
                 }
             );
-            (v: [$($arg:expr),+], [$([$($exp:expr),*]),*]) => (
+            (b: $arg:expr, [$($exp:expr),*]) => (
                 {
-                    let path = Path::new(b!($($arg),+));
+                    let path = Path::new($arg);
                     let comps = path.components().collect::<Vec<&[u8]>>();
-                    let exp: &[&[u8]] = [$(b!($($exp),*)),*];
+                    let exp: &[&[u8]] = [$($exp),*];
                     assert_eq!(comps.as_slice(), exp);
                     let comps = path.components().rev().collect::<Vec<&[u8]>>();
                     let exp = exp.iter().rev().map(|&x|x).collect::<Vec<&[u8]>>();
@@ -1205,9 +1196,9 @@ macro_rules! t(
             )
         )
 
-        t!(v: ["a/b/c"], [["a"], ["b"], ["c"]]);
-        t!(v: ["/", 0xff, "/a/", 0x80], [[0xff], ["a"], [0x80]]);
-        t!(v: ["../../foo", 0xcd, "bar"], [[".."], [".."], ["foo", 0xcd, "bar"]]);
+        t!(b: b"a/b/c", [b"a", b"b", b"c"]);
+        t!(b: b"/\xFF/a/\x80", [b"\xFF", b"a", b"\x80"]);
+        t!(b: b"../../foo\xCDbar", [b"..", b"..", b"foo\xCDbar"]);
         t!(s: "a/b/c", ["a", "b", "c"]);
         t!(s: "a/b/d", ["a", "b", "d"]);
         t!(s: "a/b/cd", ["a", "b", "cd"]);
@@ -1224,9 +1215,9 @@ macro_rules! t(
     #[test]
     fn test_str_components() {
         macro_rules! t(
-            (v: [$($arg:expr),+], $exp:expr) => (
+            (b: $arg:expr, $exp:expr) => (
                 {
-                    let path = Path::new(b!($($arg),+));
+                    let path = Path::new($arg);
                     let comps = path.str_components().collect::<Vec<Option<&str>>>();
                     let exp: &[Option<&str>] = $exp;
                     assert_eq!(comps.as_slice(), exp);
@@ -1237,9 +1228,9 @@ macro_rules! t(
             )
         )
 
-        t!(v: ["a/b/c"], [Some("a"), Some("b"), Some("c")]);
-        t!(v: ["/", 0xff, "/a/", 0x80], [None, Some("a"), None]);
-        t!(v: ["../../foo", 0xcd, "bar"], [Some(".."), Some(".."), None]);
+        t!(b: b"a/b/c", [Some("a"), Some("b"), Some("c")]);
+        t!(b: b"/\xFF/a/\x80", [None, Some("a"), None]);
+        t!(b: b"../../foo\xCDbar", [Some(".."), Some(".."), None]);
         // str_components is a wrapper around components, so no need to do
         // the full set of tests
     }
index 553c7af18cb26cb1f4d17ffca6c97b3642225d91..4d6f8d0888f3e489575ac0fcd9a916d1a2c326fb 100644 (file)
@@ -1123,15 +1123,6 @@ macro_rules! t(
         )
     )
 
-    macro_rules! b(
-        ($($arg:expr),+) => (
-            {
-                static the_bytes: &'static [u8] = bytes!($($arg),+);
-                the_bytes
-            }
-        )
-    )
-
     #[test]
     fn test_parse_prefix() {
         macro_rules! t(
@@ -1196,9 +1187,9 @@ macro_rules! t(
     #[test]
     fn test_paths() {
         let empty: &[u8] = [];
-        t!(v: Path::new(empty), b!("."));
-        t!(v: Path::new(b!("\\")), b!("\\"));
-        t!(v: Path::new(b!("a\\b\\c")), b!("a\\b\\c"));
+        t!(v: Path::new(empty), b".");
+        t!(v: Path::new(b"\\"), b"\\");
+        t!(v: Path::new(b"a\\b\\c"), b"a\\b\\c");
 
         t!(s: Path::new(""), ".");
         t!(s: Path::new("\\"), "\\");
@@ -1230,8 +1221,8 @@ fn test_paths() {
         t!(s: Path::new("foo\\..\\..\\.."), "..\\..");
         t!(s: Path::new("foo\\..\\..\\bar"), "..\\bar");
 
-        assert_eq!(Path::new(b!("foo\\bar")).into_vec().as_slice(), b!("foo\\bar"));
-        assert_eq!(Path::new(b!("\\foo\\..\\..\\bar")).into_vec().as_slice(), b!("\\bar"));
+        assert_eq!(Path::new(b"foo\\bar").into_vec().as_slice(), b"foo\\bar");
+        assert_eq!(Path::new(b"\\foo\\..\\..\\bar").into_vec().as_slice(), b"\\bar");
 
         t!(s: Path::new("\\\\a"), "\\a");
         t!(s: Path::new("\\\\a\\"), "\\a");
@@ -1284,9 +1275,9 @@ fn test_paths() {
 
     #[test]
     fn test_opt_paths() {
-        assert!(Path::new_opt(b!("foo\\bar", 0)) == None);
-        assert!(Path::new_opt(b!("foo\\bar", 0x80)) == None);
-        t!(v: Path::new_opt(b!("foo\\bar")).unwrap(), b!("foo\\bar"));
+        assert!(Path::new_opt(b"foo\\bar\0") == None);
+        assert!(Path::new_opt(b"foo\\bar\x80") == None);
+        t!(v: Path::new_opt(b"foo\\bar").unwrap(), b"foo\\bar");
         assert!(Path::new_opt("foo\\bar\0") == None);
         t!(s: Path::new_opt("foo\\bar").unwrap(), "foo\\bar");
     }
@@ -1295,17 +1286,17 @@ fn test_opt_paths() {
     fn test_null_byte() {
         use task;
         let result = task::try(proc() {
-            Path::new(b!("foo/bar", 0))
+            Path::new(b"foo/bar\0")
         });
         assert!(result.is_err());
 
         let result = task::try(proc() {
-            Path::new("test").set_filename(b!("f", 0, "o"))
+            Path::new("test").set_filename(b"f\0o")
         });
         assert!(result.is_err());
 
         let result = task::try(proc() {
-            Path::new("test").push(b!("f", 0, "o"));
+            Path::new("test").push(b"f\0o");
         });
         assert!(result.is_err());
     }
@@ -1313,20 +1304,20 @@ fn test_null_byte() {
     #[test]
     #[should_fail]
     fn test_not_utf8_fail() {
-        Path::new(b!("hello", 0x80, ".txt"));
+        Path::new(b"hello\x80.txt");
     }
 
     #[test]
     fn test_display_str() {
         let path = Path::new("foo");
         assert_eq!(path.display().to_str(), "foo".to_string());
-        let path = Path::new(b!("\\"));
+        let path = Path::new(b"\\");
         assert_eq!(path.filename_display().to_str(), "".to_string());
 
         let path = Path::new("foo");
         let mo = path.display().as_maybe_owned();
         assert_eq!(mo.as_slice(), "foo");
-        let path = Path::new(b!("\\"));
+        let path = Path::new(b"\\");
         let mo = path.filename_display().as_maybe_owned();
         assert_eq!(mo.as_slice(), "");
     }
@@ -1377,7 +1368,7 @@ macro_rules! t(
             )
         )
 
-        t!(v: b!("a\\b\\c"), filename, Some(b!("c")));
+        t!(v: b"a\\b\\c", filename, Some(b"c"));
         t!(s: "a\\b\\c", filename_str, "c");
         t!(s: "\\a\\b\\c", filename_str, "c");
         t!(s: "a", filename_str, "a");
@@ -1410,7 +1401,7 @@ macro_rules! t(
         t!(s: "\\\\.\\", filename_str, None, opt);
         t!(s: "\\\\?\\a\\b\\", filename_str, "b");
 
-        t!(v: b!("a\\b\\c"), dirname, b!("a\\b"));
+        t!(v: b"a\\b\\c", dirname, b"a\\b");
         t!(s: "a\\b\\c", dirname_str, "a\\b");
         t!(s: "\\a\\b\\c", dirname_str, "\\a\\b");
         t!(s: "a", dirname_str, ".");
@@ -1441,7 +1432,7 @@ macro_rules! t(
         t!(s: "\\\\.\\foo", dirname_str, "\\\\.\\foo");
         t!(s: "\\\\?\\a\\b\\", dirname_str, "\\\\?\\a");
 
-        t!(v: b!("hi\\there.txt"), filestem, Some(b!("there")));
+        t!(v: b"hi\\there.txt", filestem, Some(b"there"));
         t!(s: "hi\\there.txt", filestem_str, "there");
         t!(s: "hi\\there", filestem_str, "there");
         t!(s: "there.txt", filestem_str, "there");
@@ -1456,8 +1447,8 @@ macro_rules! t(
         t!(s: "..\\..", filestem_str, None, opt);
         // filestem is based on filename, so we don't need the full set of prefix tests
 
-        t!(v: b!("hi\\there.txt"), extension, Some(b!("txt")));
-        t!(v: b!("hi\\there"), extension, None);
+        t!(v: b"hi\\there.txt", extension, Some(b"txt"));
+        t!(v: b"hi\\there", extension, None);
         t!(s: "hi\\there.txt", extension_str, Some("txt"), opt);
         t!(s: "hi\\there", extension_str, None, opt);
         t!(s: "there.txt", extension_str, Some("txt"), opt);
@@ -1583,10 +1574,10 @@ macro_rules! t(
         t!(s: "a\\b\\c", ["d", "\\e"], "\\e");
         t!(s: "a\\b\\c", ["d", "\\e", "f"], "\\e\\f");
         t!(s: "a\\b\\c", ["d".to_string(), "e".to_string()], "a\\b\\c\\d\\e");
-        t!(v: b!("a\\b\\c"), [b!("d"), b!("e")], b!("a\\b\\c\\d\\e"));
-        t!(v: b!("a\\b\\c"), [b!("d"), b!("\\e"), b!("f")], b!("\\e\\f"));
-        t!(v: b!("a\\b\\c"), [Vec::from_slice(b!("d")), Vec::from_slice(b!("e"))],
-           b!("a\\b\\c\\d\\e"));
+        t!(v: b"a\\b\\c", [b"d", b"e"], b"a\\b\\c\\d\\e");
+        t!(v: b"a\\b\\c", [b"d", b"\\e", b"f"], b"\\e\\f");
+        t!(v: b"a\\b\\c", [Vec::from_slice(b"d"), Vec::from_slice(b"e")],
+           b"a\\b\\c\\d\\e");
     }
 
     #[test]
@@ -1604,11 +1595,11 @@ macro_rules! t(
                     assert!(result == $right);
                 }
             );
-            (v: [$($path:expr),+], [$($left:expr),+], $right:expr) => (
+            (b: $path:expr, $left:expr, $right:expr) => (
                 {
-                    let mut p = Path::new(b!($($path),+));
+                    let mut p = Path::new($path);
                     let result = p.pop();
-                    assert_eq!(p.as_vec(), b!($($left),+));
+                    assert_eq!(p.as_vec(), $left);
                     assert!(result == $right);
                 }
             )
@@ -1619,11 +1610,11 @@ macro_rules! t(
         t!(s: ".", ".", false);
         t!(s: "\\a", "\\", true);
         t!(s: "\\", "\\", false);
-        t!(v: ["a\\b\\c"], ["a\\b"], true);
-        t!(v: ["a"], ["."], true);
-        t!(v: ["."], ["."], false);
-        t!(v: ["\\a"], ["\\"], true);
-        t!(v: ["\\"], ["\\"], false);
+        t!(b: b"a\\b\\c", b"a\\b", true);
+        t!(b: b"a", b".", true);
+        t!(b: b".", b".", false);
+        t!(b: b"\\a", b"\\", true);
+        t!(b: b"\\", b"\\", false);
 
         t!(s: "C:\\a\\b", "C:\\a", true);
         t!(s: "C:\\a", "C:\\", true);
@@ -1672,8 +1663,8 @@ fn test_join() {
         t!(s: Path::new("a\\b").join("\\c\\d"), "\\c\\d");
         t!(s: Path::new(".").join("a\\b"), "a\\b");
         t!(s: Path::new("\\").join("a\\b"), "\\a\\b");
-        t!(v: Path::new(b!("a\\b\\c")).join(b!("..")), b!("a\\b"));
-        t!(v: Path::new(b!("\\a\\b\\c")).join(b!("d")), b!("\\a\\b\\c\\d"));
+        t!(v: Path::new(b"a\\b\\c").join(b".."), b"a\\b");
+        t!(v: Path::new(b"\\a\\b\\c").join(b"d"), b"\\a\\b\\c\\d");
         // full join testing is covered under test_push_path, so no need for
         // the full set of prefix tests
     }
@@ -1724,9 +1715,9 @@ macro_rules! t(
         t!(s: "a\\b\\c", ["..", "d"], "a\\b\\d");
         t!(s: "a\\b\\c", ["d", "\\e", "f"], "\\e\\f");
         t!(s: "a\\b\\c", ["d".to_string(), "e".to_string()], "a\\b\\c\\d\\e");
-        t!(v: b!("a\\b\\c"), [b!("d"), b!("e")], b!("a\\b\\c\\d\\e"));
-        t!(v: b!("a\\b\\c"), [Vec::from_slice(b!("d")), Vec::from_slice(b!("e"))],
-           b!("a\\b\\c\\d\\e"));
+        t!(v: b"a\\b\\c", [b"d", b"e"], b"a\\b\\c\\d\\e");
+        t!(v: b"a\\b\\c", [Vec::from_slice(b"d"), Vec::from_slice(b"e")],
+           b"a\\b\\c\\d\\e");
     }
 
     #[test]
@@ -1839,15 +1830,15 @@ macro_rules! t(
             )
         )
 
-        t!(v: b!("a\\b\\c"), set_filename, with_filename, b!("d"));
-        t!(v: b!("\\"), set_filename, with_filename, b!("foo"));
+        t!(v: b"a\\b\\c", set_filename, with_filename, b"d");
+        t!(v: b"\\", set_filename, with_filename, b"foo");
         t!(s: "a\\b\\c", set_filename, with_filename, "d");
         t!(s: "\\", set_filename, with_filename, "foo");
         t!(s: ".", set_filename, with_filename, "foo");
         t!(s: "a\\b", set_filename, with_filename, "");
         t!(s: "a", set_filename, with_filename, "");
 
-        t!(v: b!("hi\\there.txt"), set_extension, with_extension, b!("exe"));
+        t!(v: b"hi\\there.txt", set_extension, with_extension, b"exe");
         t!(s: "hi\\there.txt", set_extension, with_extension, "exe");
         t!(s: "hi\\there.", set_extension, with_extension, "txt");
         t!(s: "hi\\there", set_extension, with_extension, "txt");
@@ -1894,7 +1885,7 @@ macro_rules! t(
             )
         )
 
-        t!(v: Path::new(b!("a\\b\\c")), Some(b!("c")), b!("a\\b"), Some(b!("c")), None);
+        t!(v: Path::new(b"a\\b\\c"), Some(b"c"), b"a\\b", Some(b"c"), None);
         t!(s: Path::new("a\\b\\c"), Some("c"), Some("a\\b"), Some("c"), None);
         t!(s: Path::new("."), None, Some("."), None, None);
         t!(s: Path::new("\\"), None, Some("\\"), None, None);
@@ -2250,21 +2241,9 @@ macro_rules! t(
                     assert_eq!(comps, exp);
                 }
             );
-            (v: [$($arg:expr),+], $exp:expr) => (
-                {
-                    let path = Path::new(b!($($arg),+));
-                    let comps = path.str_components().map(|x|x.unwrap()).collect::<Vec<&str>>();
-                    let exp: &[&str] = $exp;
-                    assert_eq!(comps.as_slice(), exp);
-                    let comps = path.str_components().rev().map(|x|x.unwrap())
-                                .collect::<Vec<&str>>();
-                    let exp = exp.iter().rev().map(|&x|x).collect::<Vec<&str>>();
-                    assert_eq!(comps, exp);
-                }
-            )
         )
 
-        t!(v: ["a\\b\\c"], ["a", "b", "c"]);
+        t!(s: b"a\\b\\c", ["a", "b", "c"]);
         t!(s: "a\\b\\c", ["a", "b", "c"]);
         t!(s: "a\\b\\d", ["a", "b", "d"]);
         t!(s: "a\\b\\cd", ["a", "b", "cd"]);
@@ -2320,8 +2299,8 @@ macro_rules! t(
             )
         )
 
-        t!(s: "a\\b\\c", [b!("a"), b!("b"), b!("c")]);
-        t!(s: ".", [b!(".")]);
+        t!(s: "a\\b\\c", [b"a", b"b", b"c"]);
+        t!(s: ".", [b"."]);
         // since this is really a wrapper around str_components, those tests suffice
     }
 
index f543188af4295a628f946fbf89baa870fe86b11a..0ead8fa6c0c839b082c97dbaf6aa6dc9bae5b247 100644 (file)
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/*!
- * Utilities for managing and scheduling tasks
- *
- * An executing Rust program consists of a collection of tasks, each with their
- * own stack, and sole ownership of their allocated heap data. Tasks communicate
- * with each other using channels (see `std::comm` for more info about how
- * communication works).
- *
- * Failure in one task does not propagate to any others (not to parent, not to
- * child).  Failure propagation is instead handled by using the channel send()
- * and recv() methods which will fail if the other end has hung up already.
- *
- * Task Scheduling:
- *
- * By default, every task is created with the same "flavor" as the calling task.
- * This flavor refers to the scheduling mode, with two possibilities currently
- * being 1:1 and M:N modes. Green (M:N) tasks are cooperatively scheduled and
- * native (1:1) tasks are scheduled by the OS kernel.
- *
- * # Example
- *
- * ```rust
- * spawn(proc() {
- *     println!("Hello, World!");
- * })
- * ```
- */
+//! Utilities for managing and scheduling tasks
+//!
+//! An executing Rust program consists of a collection of lightweight tasks,
+//! each with their own stack. Tasks communicate with each other using channels
+//! (see `std::comm`) or other forms of synchronization (see `std::sync`) that
+//! ensure data-race freedom.
+//!
+//! Failure in one task does immediately propagate to any others (not to parent,
+//! not to child). Failure propagation is instead handled as part of task
+//! synchronization. For example, the channel `send()` and `recv()` methods will
+//! fail if the other end has hung up already.
+//!
+//! # Basic task scheduling
+//!
+//! By default, every task is created with the same "flavor" as the calling task.
+//! This flavor refers to the scheduling mode, with two possibilities currently
+//! being 1:1 and M:N modes. Green (M:N) tasks are cooperatively scheduled and
+//! native (1:1) tasks are scheduled by the OS kernel.
+//!
+//! ## Example
+//!
+//! ```rust
+//! spawn(proc() {
+//!     println!("Hello, World!");
+//! })
+//! ```
+//!
+//! # Advanced task scheduling
+//!
+//! Task spawning can also be configured to use a particular scheduler, to
+//! redirect the new task's output, or to yield a `future` representing the
+//! task's final result. The configuration is established using the
+//! `TaskBuilder` API:
+//!
+//! ## Example
+//!
+//! ```rust
+//! extern crate green;
+//! extern crate native;
+//!
+//! use std::task::TaskBuilder;
+//! use green::{SchedPool, PoolConfig, GreenTaskBuilder};
+//! use native::NativeTaskBuilder;
+//!
+//! # fn main() {
+//! // Create a green scheduler pool with the default configuration
+//! let mut pool = SchedPool::new(PoolConfig::new());
+//!
+//! // Spawn a task in the green pool
+//! let mut fut_green = TaskBuilder::new().green(&mut pool).try_future(proc() {
+//!     /* ... */
+//! });
+//!
+//! // Spawn a native task
+//! let mut fut_native = TaskBuilder::new().native().try_future(proc() {
+//!     /* ... */
+//! });
+//!
+//! // Wait for both tasks to finish, recording their outcome
+//! let res_green  = fut_green.unwrap();
+//! let res_native = fut_native.unwrap();
+//!
+//! // Shut down the green scheduler pool
+//! pool.shutdown();
+//! # }
+//! ```
 
 use any::Any;
-use comm::{Sender, Receiver, channel};
+use comm::channel;
 use io::{Writer, stdio};
 use kinds::{Send, marker};
 use option::{None, Some, Option};
 use owned::Box;
-use result::{Result, Ok, Err};
+use result::Result;
 use rt::local::Local;
 use rt::task;
 use rt::task::Task;
 use str::{Str, SendStr, IntoMaybeOwned};
+use sync::Future;
 
-#[cfg(test)] use any::AnyRefExt;
-#[cfg(test)] use owned::AnyOwnExt;
-#[cfg(test)] use result;
-#[cfg(test)] use str::StrAllocating;
-#[cfg(test)] use string::String;
-
-/// Task configuration options
-pub struct TaskOpts {
-    /// Enable lifecycle notifications on the given channel
-    pub notify_chan: Option<Sender<task::Result>>,
-    /// A name for the task-to-be, for identification in failure messages
-    pub name: Option<SendStr>,
-    /// The size of the stack for the spawned task
-    pub stack_size: Option<uint>,
-    /// Task-local stdout
-    pub stdout: Option<Box<Writer + Send>>,
-    /// Task-local stderr
-    pub stderr: Option<Box<Writer + Send>>,
+/// A means of spawning a task
+pub trait Spawner {
+    /// Spawn a task, given low-level task options.
+    fn spawn(self, opts: task::TaskOpts, f: proc():Send);
 }
 
-/**
- * The task builder type.
- *
- * Provides detailed control over the properties and behavior of new tasks.
- */
+/// The default task spawner, which spawns siblings to the current task.
+pub struct SiblingSpawner;
+
+impl Spawner for SiblingSpawner {
+    fn spawn(self, opts: task::TaskOpts, f: proc():Send) {
+        // bind tb to provide type annotation
+        let tb: Option<Box<Task>> = Local::try_take();
+        match tb {
+            Some(t) => t.spawn_sibling(opts, f),
+            None => fail!("need a local task to spawn a sibling task"),
+        };
+    }
+}
+
+/// The task builder type.
+///
+/// Provides detailed control over the properties and behavior of new tasks.
+
 // NB: Builders are designed to be single-use because they do stateful
 // things that get weird when reusing - e.g. if you create a result future
 // it only applies to a single task, so then you have to maintain Some
@@ -80,75 +119,102 @@ pub struct TaskOpts {
 // when you try to reuse the builder to spawn a new task. We'll just
 // sidestep that whole issue by making builders uncopyable and making
 // the run function move them in.
-pub struct TaskBuilder {
-    /// Options to spawn the new task with
-    pub opts: TaskOpts,
-    gen_body: Option<proc(v: proc(): Send): Send -> proc(): Send>,
+pub struct TaskBuilder<S = SiblingSpawner> {
+    // A name for the task-to-be, for identification in failure messages
+    name: Option<SendStr>,
+    // The size of the stack for the spawned task
+    stack_size: Option<uint>,
+    // Task-local stdout
+    stdout: Option<Box<Writer + Send>>,
+    // Task-local stderr
+    stderr: Option<Box<Writer + Send>>,
+    // The mechanics of actually spawning the task (i.e.: green or native)
+    spawner: S,
+    // Optionally wrap the eventual task body
+    gen_body: Option<proc(v: proc():Send):Send -> proc():Send>,
     nocopy: marker::NoCopy,
 }
 
-impl TaskBuilder {
-     /// Generate the base configuration for spawning a task, off of which more
-     /// configuration methods can be chained.
-    pub fn new() -> TaskBuilder {
+impl TaskBuilder<SiblingSpawner> {
+    /// Generate the base configuration for spawning a task, off of which more
+    /// configuration methods can be chained.
+    pub fn new() -> TaskBuilder<SiblingSpawner> {
         TaskBuilder {
-            opts: TaskOpts::new(),
+            name: None,
+            stack_size: None,
+            stdout: None,
+            stderr: None,
+            spawner: SiblingSpawner,
             gen_body: None,
             nocopy: marker::NoCopy,
         }
     }
+}
 
-    /// Get a future representing the exit status of the task.
-    ///
-    /// Taking the value of the future will block until the child task
-    /// terminates. The future result return value will be created *before* the task is
-    /// spawned; as such, do not invoke .get() on it directly;
-    /// rather, store it in an outer variable/list for later use.
-    ///
-    /// # Failure
-    /// Fails if a future_result was already set for this task.
-    pub fn future_result(&mut self) -> Receiver<task::Result> {
-        // FIXME (#3725): Once linked failure and notification are
-        // handled in the library, I can imagine implementing this by just
-        // registering an arbitrary number of task::on_exit handlers and
-        // sending out messages.
-
-        if self.opts.notify_chan.is_some() {
-            fail!("Can't set multiple future_results for one task!");
-        }
-
-        // Construct the future and give it to the caller.
-        let (tx, rx) = channel();
+impl<S: Spawner> TaskBuilder<S> {
+    /// Name the task-to-be. Currently the name is used for identification
+    /// only in failure messages.
+    pub fn named<T: IntoMaybeOwned<'static>>(mut self, name: T) -> TaskBuilder<S> {
+        self.name = Some(name.into_maybe_owned());
+        self
+    }
 
-        // Reconfigure self to use a notify channel.
-        self.opts.notify_chan = Some(tx);
+    /// Set the size of the stack for the new task.
+    pub fn stack_size(mut self, size: uint) -> TaskBuilder<S> {
+        self.stack_size = Some(size);
+        self
+    }
 
-        rx
+    /// Redirect task-local stdout.
+    pub fn stdout(mut self, stdout: Box<Writer + Send>) -> TaskBuilder<S> {
+        self.stdout = Some(stdout);
+        self
     }
 
-    /// Name the task-to-be. Currently the name is used for identification
-    /// only in failure messages.
-    pub fn named<S: IntoMaybeOwned<'static>>(mut self, name: S) -> TaskBuilder {
-        self.opts.name = Some(name.into_maybe_owned());
+    /// Redirect task-local stderr.
+    pub fn stderr(mut self, stderr: Box<Writer + Send>) -> TaskBuilder<S> {
+        self.stderr = Some(stderr);
         self
     }
 
-    /**
-     * Add a wrapper to the body of the spawned task.
-     *
-     * Before the task is spawned it is passed through a 'body generator'
-     * function that may perform local setup operations as well as wrap
-     * the task body in remote setup operations. With this the behavior
-     * of tasks can be extended in simple ways.
-     *
-     * This function augments the current body generator with a new body
-     * generator by applying the task body which results from the
-     * existing body generator to the new body generator.
-     */
-    pub fn with_wrapper(mut self,
-                        wrapper: proc(v: proc(): Send): Send -> proc(): Send)
-        -> TaskBuilder
-    {
+    /// Set the spawning mechanism for the task.
+    ///
+    /// The `TaskBuilder` API configures a task to be spawned, but defers to the
+    /// "spawner" to actually create and spawn the task. The `spawner` method
+    /// should not be called directly by `TaskBuiler` clients. It is intended
+    /// for use by downstream crates (like `native` and `green`) that implement
+    /// tasks. These downstream crates then add extension methods to the
+    /// builder, like `.native()` and `.green(pool)`, that actually set the
+    /// spawner.
+    pub fn spawner<T: Spawner>(self, spawner: T) -> TaskBuilder<T> {
+        // repackage the entire TaskBuilder since its type is changing.
+        let TaskBuilder {
+            name, stack_size, stdout, stderr, spawner: _, gen_body, nocopy
+        } = self;
+        TaskBuilder {
+            name: name,
+            stack_size: stack_size,
+            stdout: stdout,
+            stderr: stderr,
+            spawner: spawner,
+            gen_body: gen_body,
+            nocopy: nocopy,
+        }
+    }
+
+    /// Add a wrapper to the body of the spawned task.
+    ///
+    /// Before the task is spawned it is passed through a 'body generator'
+    /// function that may perform local setup operations as well as wrap
+    /// the task body in remote setup operations. With this the behavior
+    /// of tasks can be extended in simple ways.
+    ///
+    /// This function augments the current body generator with a new body
+    /// generator by applying the task body which results from the
+    /// existing body generator to the new body generator.
+    #[deprecated = "this function will be removed soon"]
+    pub fn with_wrapper(mut self, wrapper: proc(v: proc():Send):Send -> proc():Send)
+                        -> TaskBuilder<S> {
         self.gen_body = match self.gen_body.take() {
             Some(prev) => Some(proc(body) { wrapper(prev(body)) }),
             None => Some(wrapper)
@@ -156,90 +222,80 @@ pub fn with_wrapper(mut self,
         self
     }
 
-    /**
-     * Creates and executes a new child task
-     *
-     * Sets up a new task with its own call stack and schedules it to run
-     * the provided unique closure. The task has the properties and behavior
-     * specified by the task_builder.
-     */
-    pub fn spawn(mut self, f: proc(): Send) {
-        let gen_body = self.gen_body.take();
-        let f = match gen_body {
+    // Where spawning actually happens (whether yielding a future or not)
+    fn spawn_internal(self, f: proc():Send,
+                      on_exit: Option<proc(Result<(), Box<Any + Send>>):Send>) {
+        let TaskBuilder {
+            name, stack_size, stdout, stderr, spawner, mut gen_body, nocopy: _
+        } = self;
+        let f = match gen_body.take() {
             Some(gen) => gen(f),
             None => f
         };
-        let t: Box<Task> = match Local::try_take() {
-            Some(t) => t,
-            None => fail!("need a local task to spawn a new task"),
-        };
-        let TaskOpts { notify_chan, name, stack_size, stdout, stderr } = self.opts;
-
         let opts = task::TaskOpts {
-            on_exit: notify_chan.map(|c| proc(r) c.send(r)),
+            on_exit: on_exit,
             name: name,
             stack_size: stack_size,
         };
         if stdout.is_some() || stderr.is_some() {
-            t.spawn_sibling(opts, proc() {
+            spawner.spawn(opts, proc() {
                 let _ = stdout.map(stdio::set_stdout);
                 let _ = stderr.map(stdio::set_stderr);
                 f();
-            });
+            })
         } else {
-            t.spawn_sibling(opts, f);
+            spawner.spawn(opts, f)
         }
     }
 
-    /**
-     * Execute a function in another task and return either the return value
-     * of the function or result::err.
-     *
-     * # Return value
-     *
-     * If the function executed successfully then try returns result::ok
-     * containing the value returned by the function. If the function fails
-     * then try returns result::err containing nil.
-     *
-     * # Failure
-     * Fails if a future_result was already set for this task.
-     */
-    pub fn try<T: Send>(mut self, f: proc(): Send -> T)
-               -> Result<T, Box<Any + Send>> {
-        let (tx, rx) = channel();
-
-        let result = self.future_result();
-
-        self.spawn(proc() {
-            tx.send(f());
-        });
-
-        match result.recv() {
-            Ok(())     => Ok(rx.recv()),
-            Err(cause) => Err(cause)
-        }
+    /// Creates and executes a new child task.
+    ///
+    /// Sets up a new task with its own call stack and schedules it to run
+    /// the provided proc. The task has the properties and behavior
+    /// specified by the `TaskBuilder`.
+    pub fn spawn(self, f: proc():Send) {
+        self.spawn_internal(f, None)
     }
-}
-
-/* Task construction */
 
-impl TaskOpts {
-    pub fn new() -> TaskOpts {
-        /*!
-         * The default task options
-         */
+    /// Execute a proc in a newly-spawned task and return a future representing
+    /// the task's result. The task has the properties and behavior
+    /// specified by the `TaskBuilder`.
+    ///
+    /// Taking the value of the future will block until the child task
+    /// terminates.
+    ///
+    /// # Return value
+    ///
+    /// If the child task executes successfully (without failing) then the
+    /// future returns `result::Ok` containing the value returned by the
+    /// function. If the child task fails then the future returns `result::Err`
+    /// containing the argument to `fail!(...)` as an `Any` trait object.
+    pub fn try_future<T:Send>(self, f: proc():Send -> T)
+                              -> Future<Result<T, Box<Any + Send>>> {
+        // currently, the on_exit proc provided by librustrt only works for unit
+        // results, so we use an additional side-channel to communicate the
+        // result.
+
+        let (tx_done, rx_done) = channel(); // signal that task has exited
+        let (tx_retv, rx_retv) = channel(); // return value from task
+
+        let on_exit = proc(res) { tx_done.send(res) };
+        self.spawn_internal(proc() { tx_retv.send(f()) },
+                            Some(on_exit));
+
+        Future::from_fn(proc() {
+            rx_done.recv().map(|_| rx_retv.recv())
+        })
+    }
 
-        TaskOpts {
-            notify_chan: None,
-            name: None,
-            stack_size: None,
-            stdout: None,
-            stderr: None,
-        }
+    /// Execute a function in a newly-spawnedtask and block until the task
+    /// completes or fails. Equivalent to `.try_future(f).unwrap()`.
+    pub fn try<T:Send>(self, f: proc():Send -> T) -> Result<T, Box<Any + Send>> {
+        self.try_future(f).unwrap()
     }
 }
 
-/* Spawn convenience functions */
+/* Convenience functions */
 
 /// Creates and executes a new child task
 ///
@@ -251,14 +307,22 @@ pub fn spawn(f: proc(): Send) {
     TaskBuilder::new().spawn(f)
 }
 
-/// Execute a function in another task and return either the return value of
-/// the function or an error if the task failed
+/// Execute a function in a newly-spawned task and return either the return
+/// value of the function or an error if the task failed.
 ///
-/// This is equivalent to TaskBuilder::new().try
+/// This is equivalent to `TaskBuilder::new().try`.
 pub fn try<T: Send>(f: proc(): Send -> T) -> Result<T, Box<Any + Send>> {
     TaskBuilder::new().try(f)
 }
 
+/// Execute a function in another task and return a future representing the
+/// task's result.
+///
+/// This is equivalent to `TaskBuilder::new().try_future`.
+pub fn try_future<T:Send>(f: proc():Send -> T) -> Future<Result<T, Box<Any + Send>>> {
+    TaskBuilder::new().try_future(f)
+}
+
 
 /* Lifecycle functions */
 
@@ -273,9 +337,8 @@ pub fn with_task_name<U>(blk: |Option<&str>| -> U) -> U {
     }
 }
 
+/// Yield control to the task scheduler.
 pub fn deschedule() {
-    //! Yield control to the task scheduler
-
     use rt::local::Local;
 
     // FIXME(#7544): Optimize this, since we know we won't block.
@@ -283,266 +346,282 @@ pub fn deschedule() {
     task.yield_now();
 }
 
+/// True if the running task is currently failing (e.g. will return `true` inside a
+/// destructor that is run while unwinding the stack after a call to `fail!()`).
 pub fn failing() -> bool {
-    //! True if the running task has failed
     use rt::task::Task;
     Local::borrow(None::<Task>).unwinder.unwinding()
 }
 
-// The following 8 tests test the following 2^3 combinations:
-// {un,}linked {un,}supervised failure propagation {up,down}wards.
-
-// !!! These tests are dangerous. If Something is buggy, they will hang, !!!
-// !!! instead of exiting cleanly. This might wedge the buildbots.       !!!
-
-#[test]
-fn test_unnamed_task() {
-    spawn(proc() {
-        with_task_name(|name| {
-            assert!(name.is_none());
+#[cfg(test)]
+mod test {
+    use any::{Any, AnyRefExt};
+    use owned::AnyOwnExt;
+    use result;
+    use result::{Ok, Err};
+    use str::StrAllocating;
+    use string::String;
+    use std::io::{ChanReader, ChanWriter};
+    use prelude::*;
+    use super::*;
+
+    // !!! These tests are dangerous. If something is buggy, they will hang, !!!
+    // !!! instead of exiting cleanly. This might wedge the buildbots.       !!!
+
+    #[test]
+    fn test_unnamed_task() {
+        spawn(proc() {
+            with_task_name(|name| {
+                assert!(name.is_none());
+            })
         })
-    })
-}
+    }
 
-#[test]
-fn test_owned_named_task() {
-    TaskBuilder::new().named("ada lovelace".to_string()).spawn(proc() {
-        with_task_name(|name| {
-            assert!(name.unwrap() == "ada lovelace");
+    #[test]
+    fn test_owned_named_task() {
+        TaskBuilder::new().named("ada lovelace".to_string()).spawn(proc() {
+            with_task_name(|name| {
+                assert!(name.unwrap() == "ada lovelace");
+            })
         })
-    })
-}
+    }
 
-#[test]
-fn test_static_named_task() {
-    TaskBuilder::new().named("ada lovelace").spawn(proc() {
-        with_task_name(|name| {
-            assert!(name.unwrap() == "ada lovelace");
+    #[test]
+    fn test_static_named_task() {
+        TaskBuilder::new().named("ada lovelace").spawn(proc() {
+            with_task_name(|name| {
+                assert!(name.unwrap() == "ada lovelace");
+            })
         })
-    })
-}
+    }
 
-#[test]
-fn test_send_named_task() {
-    TaskBuilder::new().named("ada lovelace".into_maybe_owned()).spawn(proc() {
-        with_task_name(|name| {
-            assert!(name.unwrap() == "ada lovelace");
+    #[test]
+    fn test_send_named_task() {
+        TaskBuilder::new().named("ada lovelace".into_maybe_owned()).spawn(proc() {
+            with_task_name(|name| {
+                assert!(name.unwrap() == "ada lovelace");
+            })
         })
-    })
-}
-
-#[test]
-fn test_run_basic() {
-    let (tx, rx) = channel();
-    TaskBuilder::new().spawn(proc() {
-        tx.send(());
-    });
-    rx.recv();
-}
+    }
 
-#[test]
-fn test_with_wrapper() {
-    let (tx, rx) = channel();
-    TaskBuilder::new().with_wrapper(proc(body) {
-        let result: proc(): Send = proc() {
-            body();
+    #[test]
+    fn test_run_basic() {
+        let (tx, rx) = channel();
+        TaskBuilder::new().spawn(proc() {
             tx.send(());
-        };
-        result
-    }).spawn(proc() { });
-    rx.recv();
-}
+        });
+        rx.recv();
+    }
 
-#[test]
-fn test_future_result() {
-    let mut builder = TaskBuilder::new();
-    let result = builder.future_result();
-    builder.spawn(proc() {});
-    assert!(result.recv().is_ok());
-
-    let mut builder = TaskBuilder::new();
-    let result = builder.future_result();
-    builder.spawn(proc() {
-        fail!();
-    });
-    assert!(result.recv().is_err());
-}
+    #[test]
+    fn test_with_wrapper() {
+        let (tx, rx) = channel();
+        TaskBuilder::new().with_wrapper(proc(body) {
+            let result: proc():Send = proc() {
+                body();
+                tx.send(());
+            };
+            result
+        }).spawn(proc() { });
+        rx.recv();
+    }
 
-#[test] #[should_fail]
-fn test_back_to_the_future_result() {
-    let mut builder = TaskBuilder::new();
-    builder.future_result();
-    builder.future_result();
-}
+    #[test]
+    fn test_try_future() {
+        let result = TaskBuilder::new().try_future(proc() {});
+        assert!(result.unwrap().is_ok());
 
-#[test]
-fn test_try_success() {
-    match try(proc() {
-        "Success!".to_string()
-    }).as_ref().map(|s| s.as_slice()) {
-        result::Ok("Success!") => (),
-        _ => fail!()
+        let result = TaskBuilder::new().try_future(proc() -> () {
+            fail!();
+        });
+        assert!(result.unwrap().is_err());
     }
-}
 
-#[test]
-fn test_try_fail() {
-    match try(proc() {
-        fail!()
-    }) {
-        result::Err(_) => (),
-        result::Ok(()) => fail!()
+    #[test]
+    fn test_try_success() {
+        match try(proc() {
+            "Success!".to_string()
+        }).as_ref().map(|s| s.as_slice()) {
+            result::Ok("Success!") => (),
+            _ => fail!()
+        }
     }
-}
 
-#[test]
-fn test_spawn_sched() {
-    use clone::Clone;
+    #[test]
+    fn test_try_fail() {
+        match try(proc() {
+            fail!()
+        }) {
+            result::Err(_) => (),
+            result::Ok(()) => fail!()
+        }
+    }
 
-    let (tx, rx) = channel();
+    #[test]
+    fn test_spawn_sched() {
+        use clone::Clone;
 
-    fn f(i: int, tx: Sender<()>) {
-        let tx = tx.clone();
-        spawn(proc() {
-            if i == 0 {
-                tx.send(());
-            } else {
-                f(i - 1, tx);
-            }
-        });
+        let (tx, rx) = channel();
 
+        fn f(i: int, tx: Sender<()>) {
+            let tx = tx.clone();
+            spawn(proc() {
+                if i == 0 {
+                    tx.send(());
+                } else {
+                    f(i - 1, tx);
+                }
+            });
+
+        }
+        f(10, tx);
+        rx.recv();
     }
-    f(10, tx);
-    rx.recv();
-}
 
-#[test]
-fn test_spawn_sched_childs_on_default_sched() {
-    let (tx, rx) = channel();
+    #[test]
+    fn test_spawn_sched_childs_on_default_sched() {
+        let (tx, rx) = channel();
 
-    spawn(proc() {
         spawn(proc() {
-            tx.send(());
+            spawn(proc() {
+                tx.send(());
+            });
         });
-    });
 
-    rx.recv();
-}
+        rx.recv();
+    }
 
-#[cfg(test)]
-fn avoid_copying_the_body(spawnfn: |v: proc(): Send|) {
-    let (tx, rx) = channel::<uint>();
+    fn avoid_copying_the_body(spawnfn: |v: proc():Send|) {
+        let (tx, rx) = channel::<uint>();
 
-    let x = box 1;
-    let x_in_parent = (&*x) as *int as uint;
+        let x = box 1;
+        let x_in_parent = (&*x) as *int as uint;
 
-    spawnfn(proc() {
-        let x_in_child = (&*x) as *int as uint;
-        tx.send(x_in_child);
-    });
+        spawnfn(proc() {
+            let x_in_child = (&*x) as *int as uint;
+            tx.send(x_in_child);
+        });
 
-    let x_in_child = rx.recv();
-    assert_eq!(x_in_parent, x_in_child);
-}
+        let x_in_child = rx.recv();
+        assert_eq!(x_in_parent, x_in_child);
+    }
 
-#[test]
-fn test_avoid_copying_the_body_spawn() {
-    avoid_copying_the_body(spawn);
-}
+    #[test]
+    fn test_avoid_copying_the_body_spawn() {
+        avoid_copying_the_body(spawn);
+    }
 
-#[test]
-fn test_avoid_copying_the_body_task_spawn() {
-    avoid_copying_the_body(|f| {
-        let builder = TaskBuilder::new();
-        builder.spawn(proc() {
-            f();
-        });
-    })
-}
+    #[test]
+    fn test_avoid_copying_the_body_task_spawn() {
+        avoid_copying_the_body(|f| {
+            let builder = TaskBuilder::new();
+            builder.spawn(proc() {
+                f();
+            });
+        })
+    }
 
-#[test]
-fn test_avoid_copying_the_body_try() {
-    avoid_copying_the_body(|f| {
-        let _ = try(proc() {
-            f()
-        });
-    })
-}
+    #[test]
+    fn test_avoid_copying_the_body_try() {
+        avoid_copying_the_body(|f| {
+            let _ = try(proc() {
+                f()
+            });
+        })
+    }
 
-#[test]
-fn test_child_doesnt_ref_parent() {
-    // If the child refcounts the parent task, this will stack overflow when
-    // climbing the task tree to dereference each ancestor. (See #1789)
-    // (well, it would if the constant were 8000+ - I lowered it to be more
-    // valgrind-friendly. try this at home, instead..!)
-    static generations: uint = 16;
-    fn child_no(x: uint) -> proc(): Send {
-        return proc() {
-            if x < generations {
-                TaskBuilder::new().spawn(child_no(x+1));
+    #[test]
+    fn test_child_doesnt_ref_parent() {
+        // If the child refcounts the parent task, this will stack overflow when
+        // climbing the task tree to dereference each ancestor. (See #1789)
+        // (well, it would if the constant were 8000+ - I lowered it to be more
+        // valgrind-friendly. try this at home, instead..!)
+        static generations: uint = 16;
+        fn child_no(x: uint) -> proc(): Send {
+            return proc() {
+                if x < generations {
+                    TaskBuilder::new().spawn(child_no(x+1));
+                }
             }
         }
+        TaskBuilder::new().spawn(child_no(0));
     }
-    TaskBuilder::new().spawn(child_no(0));
-}
 
-#[test]
-fn test_simple_newsched_spawn() {
-    spawn(proc()())
-}
+    #[test]
+    fn test_simple_newsched_spawn() {
+        spawn(proc()())
+    }
 
-#[test]
-fn test_try_fail_message_static_str() {
-    match try(proc() {
-        fail!("static string");
-    }) {
-        Err(e) => {
-            type T = &'static str;
-            assert!(e.is::<T>());
-            assert_eq!(*e.move::<T>().unwrap(), "static string");
+    #[test]
+    fn test_try_fail_message_static_str() {
+        match try(proc() {
+            fail!("static string");
+        }) {
+            Err(e) => {
+                type T = &'static str;
+                assert!(e.is::<T>());
+                assert_eq!(*e.move::<T>().unwrap(), "static string");
+            }
+            Ok(()) => fail!()
         }
-        Ok(()) => fail!()
     }
-}
 
-#[test]
-fn test_try_fail_message_owned_str() {
-    match try(proc() {
-        fail!("owned string".to_string());
-    }) {
-        Err(e) => {
-            type T = String;
-            assert!(e.is::<T>());
-            assert_eq!(*e.move::<T>().unwrap(), "owned string".to_string());
+    #[test]
+    fn test_try_fail_message_owned_str() {
+        match try(proc() {
+            fail!("owned string".to_string());
+        }) {
+            Err(e) => {
+                type T = String;
+                assert!(e.is::<T>());
+                assert_eq!(*e.move::<T>().unwrap(), "owned string".to_string());
+            }
+            Ok(()) => fail!()
         }
-        Ok(()) => fail!()
     }
-}
 
-#[test]
-fn test_try_fail_message_any() {
-    match try(proc() {
-        fail!(box 413u16 as Box<Any + Send>);
-    }) {
-        Err(e) => {
-            type T = Box<Any + Send>;
-            assert!(e.is::<T>());
-            let any = e.move::<T>().unwrap();
-            assert!(any.is::<u16>());
-            assert_eq!(*any.move::<u16>().unwrap(), 413u16);
+    #[test]
+    fn test_try_fail_message_any() {
+        match try(proc() {
+            fail!(box 413u16 as Box<Any + Send>);
+        }) {
+            Err(e) => {
+                type T = Box<Any + Send>;
+                assert!(e.is::<T>());
+                let any = e.move::<T>().unwrap();
+                assert!(any.is::<u16>());
+                assert_eq!(*any.move::<u16>().unwrap(), 413u16);
+            }
+            Ok(()) => fail!()
         }
-        Ok(()) => fail!()
     }
-}
 
-#[test]
-fn test_try_fail_message_unit_struct() {
-    struct Juju;
+    #[test]
+    fn test_try_fail_message_unit_struct() {
+        struct Juju;
+
+        match try(proc() {
+            fail!(Juju)
+        }) {
+            Err(ref e) if e.is::<Juju>() => {}
+            Err(_) | Ok(()) => fail!()
+        }
+    }
+
+    #[test]
+    fn test_stdout() {
+        let (tx, rx) = channel();
+        let mut reader = ChanReader::new(rx);
+        let stdout = ChanWriter::new(tx);
+
+        TaskBuilder::new().stdout(box stdout as Box<Writer + Send>).try(proc() {
+            print!("Hello, world!");
+        }).unwrap();
 
-    match try(proc() {
-        fail!(Juju)
-    }) {
-        Err(ref e) if e.is::<Juju>() => {}
-        Err(_) | Ok(()) => fail!()
+        let output = reader.read_to_str().unwrap();
+        assert_eq!(output, "Hello, world!".to_string());
     }
+
+    // NOTE: the corresponding test for stderr is in run-pass/task-stderr, due
+    // to the test harness apparently interfering with stderr configuration.
 }
index d7990068d5eb7174148b46b97418add571d217e9..1fe8e8fc0db346d935ce45ad723744374484be83 100644 (file)
@@ -459,7 +459,7 @@ mod tests {
     use std::prelude::*;
     use std::comm::Empty;
     use std::task;
-    use std::task::TaskBuilder;
+    use std::task::try_future;
 
     use Arc;
     use super::{Mutex, Barrier, RWLock};
@@ -629,17 +629,15 @@ fn test_rw_arc() {
         let mut children = Vec::new();
         for _ in range(0, 5) {
             let arc3 = arc.clone();
-            let mut builder = TaskBuilder::new();
-            children.push(builder.future_result());
-            builder.spawn(proc() {
+            children.push(try_future(proc() {
                 let lock = arc3.read();
                 assert!(*lock >= 0);
-            });
+            }));
         }
 
         // Wait for children to pass their asserts
         for r in children.mut_iter() {
-            assert!(r.recv().is_ok());
+            assert!(r.get_ref().is_ok());
         }
 
         // Wait for writer to finish
index b87a25d4a44a25c87baf3f2651e18265ac6d828b..ce13fa2a7c6eee50d99055d4bde4cb4806eee1f3 100644 (file)
 
 pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                          -> Box<base::MacResult> {
+    cx.span_warn(sp, "`bytes!` is deprecated, use `b\"foo\"` literals instead");
+    cx.parse_sess.span_diagnostic.span_note(sp,
+        "see http://doc.rust-lang.org/rust.html#byte-and-byte-string-literals \
+         for documentation");
+    cx.parse_sess.span_diagnostic.span_note(sp,
+        "see https://github.com/rust-lang/rust/blob/master/src/etc/2014-06-rewrite-bytes-macros.py \
+         for an automated migration");
+
     // Gather all argument expressions
     let exprs = match get_exprs_from_tts(cx, sp, tts) {
         None => return DummyResult::expr(sp),
index b49c698486450e68586e67e28f45f38b4884ad70..1a7063c495199b6676c0a4db69b42dfeadddb2c7 100644 (file)
@@ -106,7 +106,7 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
         *dst = (*src).clone();
     }
 
-    for c in cap.iter().map(|&x| x) {
+    for &c in cap.iter() {
         let cur = c as char;
         let mut old_state = state;
         match state {
@@ -575,25 +575,25 @@ mod test {
 
     #[test]
     fn test_basic_setabf() {
-        let s = bytes!("\\E[48;5;%p1%dm");
+        let s = b"\\E[48;5;%p1%dm";
         assert_eq!(expand(s, [Number(1)], &mut Variables::new()).unwrap(),
-                   bytes!("\\E[48;5;1m").iter().map(|x| *x).collect());
+                   "\\E[48;5;1m".bytes().collect());
     }
 
     #[test]
     fn test_multiple_int_constants() {
-        assert_eq!(expand(bytes!("%{1}%{2}%d%d"), [], &mut Variables::new()).unwrap(),
-                   bytes!("21").iter().map(|x| *x).collect());
+        assert_eq!(expand(b"%{1}%{2}%d%d", [], &mut Variables::new()).unwrap(),
+                   "21".bytes().collect());
     }
 
     #[test]
     fn test_op_i() {
         let mut vars = Variables::new();
-        assert_eq!(expand(bytes!("%p1%d%p2%d%p3%d%i%p1%d%p2%d%p3%d"),
+        assert_eq!(expand(b"%p1%d%p2%d%p3%d%i%p1%d%p2%d%p3%d",
                           [Number(1),Number(2),Number(3)], &mut vars),
-                   Ok(bytes!("123233").iter().map(|x| *x).collect()));
-        assert_eq!(expand(bytes!("%p1%d%p2%d%i%p1%d%p2%d"), [], &mut vars),
-                   Ok(bytes!("0011").iter().map(|x| *x).collect()));
+                   Ok("123233".bytes().collect()));
+        assert_eq!(expand(b"%p1%d%p2%d%i%p1%d%p2%d", [], &mut vars),
+                   Ok("0011".bytes().collect()));
     }
 
     #[test]
@@ -610,7 +610,7 @@ fn test_param_stack_failure_conditions() {
             } else {
                 Number(97)
             };
-            let res = expand(bytes!("%p1").iter().map(|x| *x).collect::<Vec<_>>()
+            let res = expand("%p1".bytes().collect::<Vec<_>>()
                              .append(cap.as_bytes()).as_slice(),
                              [p],
                              vars);
@@ -622,13 +622,13 @@ fn test_param_stack_failure_conditions() {
             let res = expand(cap.as_bytes(), [], vars);
             assert!(res.is_err(),
                     "Binop {} succeeded incorrectly with 0 stack entries", *cap);
-            let res = expand(bytes!("%{1}").iter().map(|x| *x).collect::<Vec<_>>()
+            let res = expand("%{1}".bytes().collect::<Vec<_>>()
                              .append(cap.as_bytes()).as_slice(),
                               [],
                               vars);
             assert!(res.is_err(),
                     "Binop {} succeeded incorrectly with 1 stack entry", *cap);
-            let res = expand(bytes!("%{1}%{2}").iter().map(|x| *x).collect::<Vec<_>>()
+            let res = expand("%{1}%{2}".bytes().collect::<Vec<_>>()
                              .append(cap.as_bytes()).as_slice(),
                              [],
                              vars);
@@ -639,7 +639,7 @@ fn test_param_stack_failure_conditions() {
 
     #[test]
     fn test_push_bad_param() {
-        assert!(expand(bytes!("%pa"), [], &mut Variables::new()).is_err());
+        assert!(expand(b"%pa", [], &mut Variables::new()).is_err());
     }
 
     #[test]
@@ -664,39 +664,37 @@ fn test_comparison_ops() {
     #[test]
     fn test_conditionals() {
         let mut vars = Variables::new();
-        let s = bytes!("\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m");
+        let s = b"\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m";
         let res = expand(s, [Number(1)], &mut vars);
         assert!(res.is_ok(), res.unwrap_err());
         assert_eq!(res.unwrap(),
-                   bytes!("\\E[31m").iter().map(|x| *x).collect());
+                   "\\E[31m".bytes().collect());
         let res = expand(s, [Number(8)], &mut vars);
         assert!(res.is_ok(), res.unwrap_err());
         assert_eq!(res.unwrap(),
-                   bytes!("\\E[90m").iter().map(|x| *x).collect());
+                   "\\E[90m".bytes().collect());
         let res = expand(s, [Number(42)], &mut vars);
         assert!(res.is_ok(), res.unwrap_err());
         assert_eq!(res.unwrap(),
-                   bytes!("\\E[38;5;42m").iter().map(|x| *x).collect());
+                   "\\E[38;5;42m".bytes().collect());
     }
 
     #[test]
     fn test_format() {
         let mut varstruct = Variables::new();
         let vars = &mut varstruct;
-        assert_eq!(expand(bytes!("%p1%s%p2%2s%p3%2s%p4%.2s"),
+        assert_eq!(expand(b"%p1%s%p2%2s%p3%2s%p4%.2s",
                           [String("foo".to_string()),
                            String("foo".to_string()),
                            String("f".to_string()),
                            String("foo".to_string())], vars),
-                   Ok(bytes!("foofoo ffo").iter().map(|x| *x).collect()));
-        assert_eq!(expand(bytes!("%p1%:-4.2s"), [String("foo".to_string())], vars),
-                   Ok(bytes!("fo  ").iter().map(|x| *x).collect()));
-
-        assert_eq!(expand(bytes!("%p1%d%p1%.3d%p1%5d%p1%:+d"), [Number(1)], vars),
-                   Ok(bytes!("1001    1+1").iter().map(|x| *x).collect()));
-        assert_eq!(expand(bytes!("%p1%o%p1%#o%p2%6.4x%p2%#6.4X"), [Number(15), Number(27)], vars),
-                   Ok(bytes!("17017  001b0X001B").iter()
-                                                 .map(|x| *x)
-                                                 .collect()));
+                   Ok("foofoo ffo".bytes().collect()));
+        assert_eq!(expand(b"%p1%:-4.2s", [String("foo".to_string())], vars),
+                   Ok("fo  ".bytes().collect()));
+
+        assert_eq!(expand(b"%p1%d%p1%.3d%p1%5d%p1%:+d", [Number(1)], vars),
+                   Ok("1001    1+1".bytes().collect()));
+        assert_eq!(expand(b"%p1%o%p1%#o%p2%6.4x%p2%#6.4X", [Number(15), Number(27)], vars),
+                   Ok("17017  001b0X001B".bytes().collect()));
     }
 }
index b373753613d7694f1f1b78fbebec1e9dcf3b8303..916342b67434e01348b66be7ef97016935e43624 100644 (file)
@@ -315,10 +315,10 @@ macro_rules! try( ($e:expr) => (
 /// Create a dummy TermInfo struct for msys terminals
 pub fn msys_terminfo() -> Box<TermInfo> {
     let mut strings = HashMap::new();
-    strings.insert("sgr0".to_string(), Vec::from_slice(bytes!("\x1b[0m")));
-    strings.insert("bold".to_string(), Vec::from_slice(bytes!("\x1b[1m")));
-    strings.insert("setaf".to_string(), Vec::from_slice(bytes!("\x1b[3%p1%dm")));
-    strings.insert("setab".to_string(), Vec::from_slice(bytes!("\x1b[4%p1%dm")));
+    strings.insert("sgr0".to_string(), Vec::from_slice(b"\x1B[0m"));
+    strings.insert("bold".to_string(), Vec::from_slice(b"\x1B[1m"));
+    strings.insert("setaf".to_string(), Vec::from_slice(b"\x1B[3%p1%dm"));
+    strings.insert("setab".to_string(), Vec::from_slice(b"\x1B[4%p1%dm"));
     box TermInfo {
         names: vec!("cygwin".to_string()), // msys is a fork of an older cygwin version
         bools: HashMap::new(),
index e7c35fb59eee560e219a5c6d551f2848b19a57ba..112ffd7c1a4a480899e26bbc345a25845d2f23b5 100644 (file)
@@ -1049,14 +1049,13 @@ fn run_test_inner(desc: TestDesc,
             if nocapture {
                 drop((stdout, stderr));
             } else {
-                task.opts.stdout = Some(box stdout as Box<Writer + Send>);
-                task.opts.stderr = Some(box stderr as Box<Writer + Send>);
+                task = task.stdout(box stdout as Box<Writer + Send>);
+                task = task.stderr(box stderr as Box<Writer + Send>);
             }
-            let result_future = task.future_result();
-            task.spawn(testfn);
+            let result_future = task.try_future(testfn);
 
             let stdout = reader.read_to_end().unwrap().move_iter().collect();
-            let task_result = result_future.recv();
+            let task_result = result_future.unwrap();
             let test_result = calc_result(&desc, task_result.is_ok());
             monitor_ch.send((desc.clone(), test_result, stdout));
         })
index bace30e3f6ffd1dc5afbdbd842fa305ca1d4724a..b68b435da4bb0a7d427504083e4586d6fa4a5fce 100644 (file)
@@ -209,8 +209,6 @@ pub fn new_v4() -> Uuid {
     /// * `d3` A 16-bit word
     /// * `d4` Array of 8 octets
     pub fn from_fields(d1: u32, d2: u16, d3: u16, d4: &[u8]) -> Uuid {
-        use std::mem::{to_be16, to_be32};
-
         // First construct a temporary field-based struct
         let mut fields = UuidFields {
                 data1: 0,
@@ -219,9 +217,9 @@ pub fn from_fields(d1: u32, d2: u16, d3: u16, d4: &[u8]) -> Uuid {
                 data4: [0, ..8]
         };
 
-        fields.data1 = to_be32(d1);
-        fields.data2 = to_be16(d2);
-        fields.data3 = to_be16(d3);
+        fields.data1 = d1.to_be();
+        fields.data2 = d2.to_be();
+        fields.data3 = d3.to_be();
         slice::bytes::copy_memory(fields.data4, d4);
 
         unsafe {
@@ -335,16 +333,15 @@ pub fn to_simple_str(&self) -> String {
     ///
     /// Example: `550e8400-e29b-41d4-a716-446655440000`
     pub fn to_hyphenated_str(&self) -> String {
-        use std::mem::{to_be16, to_be32};
         // Convert to field-based struct as it matches groups in output.
         // Ensure fields are in network byte order, as per RFC.
         let mut uf: UuidFields;
         unsafe {
             uf = transmute_copy(&self.bytes);
         }
-        uf.data1 = to_be32(uf.data1);
-        uf.data2 = to_be16(uf.data2);
-        uf.data3 = to_be16(uf.data3);
+        uf.data1 = uf.data1.to_be();
+        uf.data2 = uf.data2.to_be();
+        uf.data3 = uf.data3.to_be();
         let s = format!("{:08x}-{:04x}-{:04x}-{:02x}{:02x}-\
                          {:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
             uf.data1,
index d528cb16e72dc73c2057a0cde7f61157d1dcb3a7..e46c99cf4f0dd9c943ab85acb4381d33e87d165c 100644 (file)
@@ -1,3 +1,11 @@
+S 2014-06-18 d6736a1
+  freebsd-x86_64 c1479bb3dc0ae3d8ba9193ff2caf92c805a95c51
+  linux-i386 bb1543b21235a51e81460b9419e112396ccf1d20
+  linux-x86_64 08df93f138bc6c9d083d28bb71384fcebf0380c1
+  macos-i386 d6c0039ad7cbd5959e69c980ecf822e5097bac2c
+  macos-x86_64 ee54924aa4103d35cf490da004d3cc4e48ca8fb0
+  winnt-i386 943c99971e82847abe272df58bb7656ac3b91430
+
 S 2014-06-14 2c6caad
   freebsd-x86_64 0152ba43f238014f0aede7c29f1c684c21077b0b
   linux-i386 2eb1897c25abe0d5978ff03171ca943e92666046
index 03d91cf3aaa7a4e35af92bb9c0a52ba6b888e280..14155d54d73ccbdf6e5afc84e0f172f213f6fe53 100644 (file)
@@ -24,7 +24,6 @@
 use std::comm;
 use std::os;
 use std::task;
-use std::task::TaskBuilder;
 use std::uint;
 
 fn move_out<T>(_x: T) {}
@@ -64,22 +63,20 @@ fn run(args: &[String]) {
     let mut worker_results = Vec::new();
     for _ in range(0u, workers) {
         let to_child = to_child.clone();
-        let mut builder = TaskBuilder::new();
-        worker_results.push(builder.future_result());
-        builder.spawn(proc() {
+        worker_results.push(task::try_future(proc() {
             for _ in range(0u, size / workers) {
                 //println!("worker {:?}: sending {:?} bytes", i, num_bytes);
                 to_child.send(bytes(num_bytes));
             }
             //println!("worker {:?} exiting", i);
-        });
+        }));
     }
     task::spawn(proc() {
         server(&from_parent, &to_parent);
     });
 
-    for r in worker_results.iter() {
-        r.recv();
+    for r in worker_results.move_iter() {
+        r.unwrap();
     }
 
     //println!("sending stop message");
index 4de51c3ab4b8e97093310845de7213c4fa2bf502..7ec2796b230a7a309ab13bd9f07794d3f6d86a2d 100644 (file)
@@ -19,7 +19,6 @@
 
 use std::os;
 use std::task;
-use std::task::TaskBuilder;
 use std::uint;
 
 fn move_out<T>(_x: T) {}
@@ -58,29 +57,25 @@ fn run(args: &[String]) {
     let mut worker_results = Vec::new();
     let from_parent = if workers == 1 {
         let (to_child, from_parent) = channel();
-        let mut builder = TaskBuilder::new();
-        worker_results.push(builder.future_result());
-        builder.spawn(proc() {
+        worker_results.push(task::try_future(proc() {
             for _ in range(0u, size / workers) {
                 //println!("worker {:?}: sending {:?} bytes", i, num_bytes);
                 to_child.send(bytes(num_bytes));
             }
             //println!("worker {:?} exiting", i);
-        });
+        }));
         from_parent
     } else {
         let (to_child, from_parent) = channel();
         for _ in range(0u, workers) {
             let to_child = to_child.clone();
-            let mut builder = TaskBuilder::new();
-            worker_results.push(builder.future_result());
-            builder.spawn(proc() {
+            worker_results.push(task::try_future(proc() {
                 for _ in range(0u, size / workers) {
                     //println!("worker {:?}: sending {:?} bytes", i, num_bytes);
                     to_child.send(bytes(num_bytes));
                 }
                 //println!("worker {:?} exiting", i);
-            });
+            }));
         }
         from_parent
     };
@@ -88,8 +83,8 @@ fn run(args: &[String]) {
         server(&from_parent, &to_parent);
     });
 
-    for r in worker_results.iter() {
-        r.recv();
+    for r in worker_results.move_iter() {
+        r.unwrap();
     }
 
     //println!("sending stop message");
index 33853a91b7608554297b259894aa940876f3ae36..57a6d0e7c523d860210f5ae230400b91e5d89c7a 100644 (file)
@@ -24,7 +24,6 @@
 use std::os;
 use std::result::{Ok, Err};
 use std::task;
-use std::task::TaskBuilder;
 use std::uint;
 
 fn fib(n: int) -> int {
@@ -79,14 +78,12 @@ fn stress_task(id: int) {
 fn stress(num_tasks: int) {
     let mut results = Vec::new();
     for i in range(0, num_tasks) {
-        let mut builder = TaskBuilder::new();
-        results.push(builder.future_result());
-        builder.spawn(proc() {
+        results.push(task::try_future(proc() {
             stress_task(i);
-        });
+        }));
     }
-    for r in results.iter() {
-        r.recv();
+    for r in results.move_iter() {
+        r.unwrap();
     }
 }
 
index c0ea6f8617d87ecadd3a60b9f98c7b52aae01656..af51157bba564d53482206d65e5b99ec46d32418 100644 (file)
@@ -16,7 +16,6 @@
 use std::io;
 use std::io::stdio::StdReader;
 use std::io::BufferedReader;
-use std::num::Bitwise;
 use std::os;
 
 // Computes a single solution to a given 9x9 sudoku
diff --git a/src/test/compile-fail/borrowck-array-double-move.rs b/src/test/compile-fail/borrowck-array-double-move.rs
new file mode 100644 (file)
index 0000000..c7fb646
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn f() {
+    let mut a = [box 0, box 1];
+    drop(a[0]);
+    a[1] = box 2;
+    drop(a[0]); //~ ERROR use of moved value: `a[..]`
+}
+
+fn main() {
+    f();
+}
+
index df2c40657c814bd84108f4d7b60943a1d831ce89..5f8352d1e5229525c003c8dac7504029aecc208a 100644 (file)
@@ -22,7 +22,8 @@ enum CantDeriveThose {}
 fn main() {
     doesnt_exist!(); //~ ERROR
 
-    bytes!(invalid); //~ ERROR
+    bytes!(invalid); //~ ERROR non-literal in bytes!
+    //~^ WARN `bytes!` is deprecated
 
     asm!(invalid); //~ ERROR
 
index f5b4342ceb7498e09586bcd61ef627b0bd375c29..d03696cbbbcc482f92eaecace20738dd0c464367 100644 (file)
@@ -10,4 +10,5 @@
 
 fn main() {
     let vec = bytes!('λ'); //~ ERROR non-ascii char literal in bytes!
+    //~^ WARN `bytes!` is deprecated
 }
index 281a5630f82c9b82898a535cc9b00051d53687d4..3a2e104818fd202435c4a5531872b20fc1db54a3 100644 (file)
@@ -10,4 +10,5 @@
 
 fn main() {
     let vec = bytes!(foo); //~ ERROR non-literal in bytes!
+    //~^ WARN `bytes!` is deprecated
 }
index 25688d7d17ab44f6228042a17a2bdf2317c98bf9..8e7c6147758ca9354e544d1879e1182943b5279c 100644 (file)
@@ -10,4 +10,5 @@
 
 fn main() {
     let vec = bytes!(1024); //~ ERROR too large integer literal in bytes!
+    //~^ WARN `bytes!` is deprecated
 }
index d1c8a2c091304354dc3b6875482dd5895915f05d..1a9aa3753eec7747827309818eaa9894d5236a27 100644 (file)
@@ -10,4 +10,5 @@
 
 fn main() {
     let vec = bytes!(1024u8); //~ ERROR too large u8 literal in bytes!
+    //~^ WARN `bytes!` is deprecated
 }
index ef45ea06003d5f9c2c2b54ff57f91796fa53ee7e..c2d4973594371e326bae074757d8482345971b03 100644 (file)
@@ -10,4 +10,5 @@
 
 fn main() {
     let vec = bytes!(-1024); //~ ERROR non-literal in bytes
+    //~^ WARN `bytes!` is deprecated
 }
index b8ba73559aa74ea019eba2b72c6f9439701c760a..ac33ffb60e294f11ba9df9373f58e980fd045125 100644 (file)
@@ -10,4 +10,5 @@
 
 fn main() {
     let vec = bytes!(-1024u8); //~ ERROR non-literal in bytes
+    //~^ WARN `bytes!` is deprecated
 }
index 142566fe8ab789f0768817bd75616a8ade1e9090..f6b3659354c5ba4ef231e571588ca0a57d2b679c 100644 (file)
@@ -10,4 +10,5 @@
 
 fn main() {
     let vec = bytes!(45f64); //~ ERROR unsupported literal in bytes!
+    //~^ WARN `bytes!` is deprecated
 }
diff --git a/src/test/debuginfo/issue14411.rs b/src/test/debuginfo/issue14411.rs
new file mode 100644 (file)
index 0000000..16c7dcc
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+
+// No debugger interaction required: just make sure it compiles without
+// crashing.
+
+fn test(a: &Vec<u8>) {
+  print!("{}", a.len());
+}
+
+pub fn main() {
+  let data = vec!();
+  test(&data);
+}
diff --git a/src/test/run-pass/issue-14865.rs b/src/test/run-pass/issue-14865.rs
new file mode 100644 (file)
index 0000000..7fa88a7
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+enum X {
+    Foo(uint),
+    Bar(bool)
+}
+
+fn main() {
+    let x = match Foo(42) {
+        Foo(..) => 1,
+        _ if true => 0,
+        Bar(..) => fail!("Oh dear")
+    };
+    assert_eq!(x, 1);
+
+    let x = match Foo(42) {
+        _ if true => 0,
+        Foo(..) => 1,
+        Bar(..) => fail!("Oh dear")
+    };
+    assert_eq!(x, 0);
+}
diff --git a/src/test/run-pass/issue-14958.rs b/src/test/run-pass/issue-14958.rs
new file mode 100644 (file)
index 0000000..045d3cc
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(overloaded_calls)]
+
+trait Foo {}
+
+struct Bar;
+
+impl<'a> std::ops::Fn<(&'a Foo,), ()> for Bar {
+    fn call(&self, _: (&'a Foo,)) {}
+}
+
+struct Baz;
+
+impl Foo for Baz {}
+
+fn main() {
+    let bar = Bar;
+    let baz = &Baz;
+    bar(baz);
+}
index f1217be3484fe99014c9f3f121ddc77e8e2693b1..4ff735708b5ab7753936e7408835ce30e9acfb39 100644 (file)
@@ -13,9 +13,7 @@
 static generations: uint = 1024+256+128+49;
 
 fn spawn(f: proc():Send) {
-    let mut t = TaskBuilder::new();
-    t.opts.stack_size = Some(32 * 1024);
-    t.spawn(f);
+    TaskBuilder::new().stack_size(32 * 1024).spawn(f)
 }
 
 fn child_no(x: uint) -> proc():Send {
index 6fb66cd3b1580a2f49f750fb84616fc2ef90cb38..fd67b767104d502ed7a27a44f7e91f5360cc91da 100644 (file)
@@ -12,5 +12,5 @@
 
 pub fn main() {
     let stdout = &mut io::stdout() as &mut io::Writer;
-    stdout.write(bytes!("Hello!"));
+    stdout.write(b"Hello!");
 }
index a78bbefed44db64eeed99d811e7c70fd9e7dbf9f..851f87adfc20dac8a0b72691db20eff460110b99 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use std::task;
-use std::task::TaskBuilder;
 
 pub fn main() { test00(); }
 
@@ -17,9 +16,7 @@
 
 fn test00() {
     let i: int = 0;
-    let mut builder = TaskBuilder::new();
-    let mut result = builder.future_result();
-    builder.spawn(proc() {
+    let mut result = task::try_future(proc() {
         start(i)
     });
 
@@ -31,7 +28,7 @@ fn test00() {
     }
 
     // Try joining tasks that have already finished.
-    result.recv();
+    result.unwrap();
 
     println!("Joined task.");
 }
index 217bab5c1dea6fdd6b032cef2aa71d33e8f1eb22..cd31d15db10925d03ae24046a89f7c364f4ba26f 100644 (file)
@@ -10,7 +10,7 @@
 
 extern crate debug;
 
-use std::task::TaskBuilder;
+use std::task;
 
 pub fn main() { println!("===== WITHOUT THREADS ====="); test00(); }
 
@@ -39,14 +39,12 @@ fn test00() {
     let mut results = Vec::new();
     while i < number_of_tasks {
         let tx = tx.clone();
-        let mut builder = TaskBuilder::new();
-        results.push(builder.future_result());
-        builder.spawn({
+        results.push(task::try_future({
             let i = i;
             proc() {
                 test00_start(&tx, i, number_of_messages)
             }
-        });
+        }));
         i = i + 1;
     }
 
@@ -62,7 +60,7 @@ fn test00() {
     }
 
     // Join spawned tasks...
-    for r in results.iter() { r.recv(); }
+    for r in results.mut_iter() { r.get_ref(); }
 
     println!("Completed: Final number is: ");
     println!("{:?}", sum);
index ab6498c00279b07be5aaf854539010a0ccce9e1f..a46b4513c5deecf0b4e12a7ead18685727c3de92 100644 (file)
@@ -10,7 +10,7 @@
 
 extern crate debug;
 
-use std::task::TaskBuilder;
+use std::task;
 
 pub fn main() { test00(); }
 
@@ -25,9 +25,7 @@ fn test00() {
     let (tx, rx) = channel();
     let number_of_messages: int = 10;
 
-    let mut builder = TaskBuilder::new();
-    let result = builder.future_result();
-    builder.spawn(proc() {
+    let result = task::try_future(proc() {
         test00_start(&tx, number_of_messages);
     });
 
@@ -38,7 +36,7 @@ fn test00() {
         i += 1;
     }
 
-    result.recv();
+    result.unwrap();
 
     assert_eq!(sum, number_of_messages * (number_of_messages - 1) / 2);
 }
diff --git a/src/test/run-pass/task-stderr.rs b/src/test/run-pass/task-stderr.rs
new file mode 100644 (file)
index 0000000..6a71f9d
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::io::{ChanReader, ChanWriter};
+use std::task::TaskBuilder;
+
+fn main() {
+    let (tx, rx) = channel();
+    let mut reader = ChanReader::new(rx);
+    let stderr = ChanWriter::new(tx);
+
+    let res = TaskBuilder::new().stderr(box stderr as Box<Writer + Send>).try(proc() -> () {
+        fail!("Hello, world!")
+    });
+    assert!(res.is_err());
+
+    let output = reader.read_to_str().unwrap();
+    assert!(output.as_slice().contains("Hello, world!"));
+}
index 9c4716e5f4d3805aa28877d4b5d41dfd34fc024e..99bf247229e059085ea5452de1286447f433b824 100644 (file)
@@ -60,9 +60,7 @@ fn main() {
     let (tx, rx) = channel();
     for _ in range(0, 1000) {
         let tx = tx.clone();
-        let mut builder = TaskBuilder::new();
-        builder.opts.stack_size = Some(64 * 1024);
-        builder.spawn(proc() {
+        TaskBuilder::new().stack_size(64 * 1024).spawn(proc() {
             let host = addr.ip.to_str();
             let port = addr.port;
             match TcpStream::connect(host.as_slice(), port) {
index 316d1facb18ff54bf8901c867461979578fd3c17..4355bf4127fc4f9c727d679a9cad16269971a985 100644 (file)
@@ -29,7 +29,7 @@ fn test_tempdir() {
     let path = {
         let p = TempDir::new_in(&Path::new("."), "foobar").unwrap();
         let p = p.path();
-        assert!(p.as_vec().ends_with(bytes!("foobar")));
+        assert!(p.as_vec().ends_with(b"foobar"));
         p.clone()
     };
     assert!(!path.exists());
index 1d229a8ae8361fab8a4f21c5ff9aefd531c8f1fb..55beebbf2bc576534000f91008729a1d0bb6af9a 100644 (file)
@@ -26,7 +26,7 @@ fn f(&self) {
 }
 
 fn foo(mut a: Box<Writer>) {
-    a.write(bytes!("Hello\n"));
+    a.write(b"Hello\n");
 }
 
 pub fn main() {
index 2662a6c6568b9834b25e333f201b629427c03632..89d204dcecbdbc03a8acd1835034b3609d2e3064 100644 (file)
@@ -9,18 +9,15 @@
 // except according to those terms.
 
 use std::task;
-use std::task::TaskBuilder;
 
 pub fn main() {
-    let mut builder = TaskBuilder::new();
-    let mut result = builder.future_result();
-    builder.spawn(child);
+    let mut result = task::try_future(child);
     println!("1");
     task::deschedule();
     println!("2");
     task::deschedule();
     println!("3");
-    result.recv();
+    result.unwrap();
 }
 
 fn child() {
index 8c5504725bb483e9e13a8f2ee40d1f118f7e75a4..d882b1abd295ddec68fa194365d6a1912dc01152 100644 (file)
@@ -9,15 +9,12 @@
 // except according to those terms.
 
 use std::task;
-use std::task::TaskBuilder;
 
 pub fn main() {
-    let mut builder = TaskBuilder::new();
-    let mut result = builder.future_result();
-    builder.spawn(child);
+    let mut result = task::try_future(child);
     println!("1");
     task::deschedule();
-    result.recv();
+    result.unwrap();
 }
 
 fn child() { println!("2"); }