diff --git a/src/compiler-rt b/src/compiler-rt index 7b97b8468f061..62a4ca6055ad6 160000 --- a/src/compiler-rt +++ b/src/compiler-rt @@ -1 +1 @@ -Subproject commit 7b97b8468f0614072cf3299fa8c51e85f609316f +Subproject commit 62a4ca6055ad6fda8faf767b93b5736dcdfb7013 diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 1e07068dd6f62..ce3c2d7de8095 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -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())) } } diff --git a/src/doc/complement-cheatsheet.md b/src/doc/complement-cheatsheet.md index 9797284a65b7d..84fd140a23af4 100644 --- a/src/doc/complement-cheatsheet.md +++ b/src/doc/complement-cheatsheet.md @@ -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); ~~~ diff --git a/src/doc/rust.md b/src/doc/rust.md index cc41b8edfbf8d..7e5e5b2e67a43 100644 --- a/src/doc/rust.md +++ b/src/doc/rust.md @@ -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 index 0000000000000..ceda4bf6fe253 --- /dev/null +++ b/src/etc/2014-06-rewrite-bytes-macros.py @@ -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 or the MIT license +# , 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 [^)]* ) \)', 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 index 0000000000000..c6b9b314da5c4 --- /dev/null +++ b/src/etc/vim/autoload/rust.vim @@ -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 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 index 0000000000000..96ed69db63529 --- /dev/null +++ b/src/etc/vim/doc/rust.txt @@ -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_* + Executes |:RustRun| with no arguments. + Note: This binding is only available in MacVim. + + *rust_* + 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: diff --git a/src/etc/vim/ftplugin/rust.vim b/src/etc/vim/ftplugin/rust.vim index b70cda9b998c4..65f9f4105ad8f 100644 --- a/src/etc/vim/ftplugin/rust.vim +++ b/src/etc/vim/ftplugin/rust.vim @@ -1,13 +1,19 @@ -" Vim syntax file " Language: Rust +" Description: Vim syntax file for Rust " Maintainer: Chris Morgan -" Last Change: 2014 Feb 27 +" Maintainer: Kevin Ballard +" 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 [[ :call Rust_Jump('n', 'Back') -nnoremap ]] :call Rust_Jump('n', 'Forward') -xnoremap [[ :call Rust_Jump('v', 'Back') -xnoremap ]] :call Rust_Jump('v', 'Forward') -onoremap [[ :call Rust_Jump('o', 'Back') -onoremap ]] :call Rust_Jump('o', 'Forward') +nnoremap [[ :call rust#Jump('n', 'Back') +nnoremap ]] :call rust#Jump('n', 'Forward') +xnoremap [[ :call rust#Jump('v', 'Back') +xnoremap ]] :call rust#Jump('v', 'Forward') +onoremap [[ :call rust#Jump('o', 'Back') +onoremap ]] :call rust#Jump('o', 'Forward') + +" Commands {{{1 + +" See |:RustRun| for docs +command! -nargs=* -complete=file -bang -bar -buffer RustRun call rust#Run(0, []) + +" See |:RustExpand| for docs +command! -nargs=* -complete=customlist,rust#CompleteExpand -bang -bar -buffer RustExpand call rust#Expand(0, []) + +" See |:RustEmitIr| for docs +command! -nargs=* -bar -buffer RustEmitIr call rust#Emit("ir", []) + +" See |:RustEmitAsm| for docs +command! -nargs=* -bar -buffer RustEmitAsm call rust#Emit("asm", []) + +" Mappings {{{1 + +" Bind ⌘R in MacVim to :RustRun +nnoremap :RustRun +" Bind ⌘⇧R in MacVim to :RustRun! pre-filled with the last args +nnoremap :RustRun! =join(b:rust_last_rustc_args)erust#AppendCmdLine(' -- ' . join(b:rust_last_args)) + +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 + \|nunmap \|nunmap [[ \|nunmap ]] \|xunmap [[ @@ -66,31 +109,9 @@ let b:undo_ftplugin = " \|ounmap ]] \" -if exists('*Rust_Jump') | finish | endif +" }}}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 Rust_Jump_" . a:function . "()" - let cnt = cnt - 1 - endwhile - let &foldenable = foldenable -endfunction - -function! Rust_Jump_Back() - call search('{', 'b') - keepjumps normal! w99[{ -endfunction - -function! 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: diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim index 77348335eb346..a0488cdb05ab4 100644 --- a/src/etc/vim/syntax/rust.vim +++ b/src/etc/vim/syntax/rust.vim @@ -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 diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index 79a616b9555aa..b4d0057778a1a 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -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")] diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index 34514fde9dbd1..1360b412c2370 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -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 { diff --git a/src/libcollections/hash/mod.rs b/src/libcollections/hash/mod.rs index bd7bab456ba01..a0c0c9f973578 100644 --- a/src/libcollections/hash/mod.rs +++ b/src/libcollections/hash/mod.rs @@ -98,46 +98,30 @@ pub trait Writer { ////////////////////////////////////////////////////////////////////////////// -fn id(t: T) -> T { t } - -macro_rules! impl_hash( - ( $($ty:ident, $uty:ident, $f:path;)* ) => ( - $( - impl Hash 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 Hash 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 Hash for bool { #[inline] diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index ff00ca58e8c76..f9826fcd2287f 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -1957,30 +1957,30 @@ mod tests { #[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] diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 83601be83dec0..642e7cfc9a36f 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -382,7 +382,7 @@ static TAG_CONT_U8: u8 = 128u8; /// # 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 @@ mod tests { 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 @@ mod tests { #[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 @@ mod bench { #[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 @@ mod bench { #[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 @@ mod bench { #[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 @@ mod bench { #[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 @@ mod bench { #[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); }); diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 237efcd0096d0..5280ac0d64fb2 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -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(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(x: &mut T, y: &mut T) { @@ -337,42 +273,40 @@ pub fn swap(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 { buf: Vec } - * - * impl Buffer { - * fn get_and_reset(&mut self) -> Vec { - * // 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 { buf: Vec } - * impl Buffer { - * fn get_and_reset(&mut self) -> Vec { - * 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 { buf: Vec } +/// +/// impl Buffer { +/// fn get_and_reset(&mut self) -> Vec { +/// // 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 { buf: Vec } +/// impl Buffer { +/// fn get_and_reset(&mut self) -> Vec { +/// use std::mem::replace; +/// replace(&mut self.buf, Vec::new()) +/// } +/// } +/// ``` #[inline] #[stable] pub fn replace(dest: &mut T, mut src: T) -> T { diff --git a/src/libcore/num/int_macros.rs b/src/libcore/num/int_macros.rs index 20bb12db694c0..79734324706b2 100644 --- a/src/libcore/num/int_macros.rs +++ b/src/libcore/num/int_macros.rs @@ -35,7 +35,6 @@ mod tests { use int; use num; - use num::Bitwise; use num::CheckedDiv; #[test] @@ -90,7 +89,7 @@ mod tests { } #[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 @@ mod tests { 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] diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index eaa632be6d04c..573470c29bcf4 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -376,217 +376,293 @@ bounded_impl!(i64, i64::MIN, i64::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 - + BitAnd - + BitOr - + BitXor - + Shl - + Shr { - /// 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 + + BitAnd + + BitOr + + BitXor + + Shl + + Shr { + /// 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] diff --git a/src/libcore/num/uint_macros.rs b/src/libcore/num/uint_macros.rs index 8e4ba10154244..be1f960bcc3df 100644 --- a/src/libcore/num/uint_macros.rs +++ b/src/libcore/num/uint_macros.rs @@ -26,7 +26,6 @@ mod tests { use num; use num::CheckedDiv; - use num::Bitwise; #[test] fn test_overflows() { @@ -41,7 +40,7 @@ mod tests { } #[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 @@ mod tests { 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] diff --git a/src/libdebug/repr.rs b/src/libdebug/repr.rs index d27b0f0de7e30..4744d92436f2b 100644 --- a/src/libdebug/repr.rs +++ b/src/libdebug/repr.rs @@ -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 diff --git a/src/libgreen/lib.rs b/src/libgreen/lib.rs index 6c3ad8a6ef961..ee25d19e324cc 100644 --- a/src/libgreen/lib.rs +++ b/src/libgreen/lib.rs @@ -159,16 +159,19 @@ //! //! # 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() { @@ -181,12 +184,9 @@ //! 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 @@ -209,6 +209,8 @@ // 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; @@ -224,8 +226,9 @@ use std::rt::task::TaskOpts; 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 @@ impl 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::configure(&mut self.stack_pool, opts, f) } @@ -454,6 +458,7 @@ impl SchedPool { /// 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 @@ impl Drop for SchedPool { } } } + +/// 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>; + fn green_pinned<'a>(self, &'a mut SchedPool, &'a mut SchedHandle) + -> TaskBuilder>; +} + +impl GreenTaskBuilder for TaskBuilder { + fn green<'a>(self, pool: &'a mut SchedPool) -> TaskBuilder> { + self.spawner(GreenSpawner {pool: pool, handle: None}) + } + + fn green_pinned<'a>(self, pool: &'a mut SchedPool, handle: &'a mut SchedHandle) + -> TaskBuilder> { + 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(); + } +} diff --git a/src/libnative/io/file_unix.rs b/src/libnative/io/file_unix.rs index 93938e3d5b860..edf2becc77760 100644 --- a/src/libnative/io/file_unix.rs +++ b/src/libnative/io/file_unix.rs @@ -360,7 +360,7 @@ pub fn readdir(p: &CString) -> IoResult> { 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 @@ mod tests { 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 @@ mod tests { 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) { diff --git a/src/libnative/io/file_win32.rs b/src/libnative/io/file_win32.rs index 41ef5e31a91f6..cd9abc70a4ee8 100644 --- a/src/libnative/io/file_win32.rs +++ b/src/libnative/io/file_win32.rs @@ -351,7 +351,7 @@ pub fn readdir(p: &CString) -> IoResult> { 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() } diff --git a/src/libnative/io/net.rs b/src/libnative/io/net.rs index 8cf0c3bf0620f..5dfae8d9efe64 100644 --- a/src/libnative/io/net.rs +++ b/src/libnative/io/net.rs @@ -27,10 +27,10 @@ use super::util; #[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; diff --git a/src/libnative/lib.rs b/src/libnative/lib.rs index f04dfac80ccfe..40b99c5bbdb1d 100644 --- a/src/libnative/lib.rs +++ b/src/libnative/lib.rs @@ -32,10 +32,13 @@ //! ```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::os; use std::rt; use std::str; +pub use task::NativeTaskBuilder; + pub mod io; pub mod task; diff --git a/src/libnative/task.rs b/src/libnative/task.rs index b073c2c7fbf02..88e581a479136 100644 --- a/src/libnative/task.rs +++ b/src/libnative/task.rs @@ -27,6 +27,7 @@ use std::rt; 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 { @@ -48,12 +49,14 @@ fn ops() -> Box { } /// 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; +} + +impl NativeTaskBuilder for TaskBuilder { + fn native(self) -> TaskBuilder { + 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 @@ mod tests { }); 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()); + } } diff --git a/src/libnum/bigint.rs b/src/libnum/bigint.rs index 0933301970d19..e9153f89e04ee 100644 --- a/src/libnum/bigint.rs +++ b/src/libnum/bigint.rs @@ -23,7 +23,7 @@ use std::{cmp, fmt}; 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}; diff --git a/src/librand/lib.rs b/src/librand/lib.rs index 5a9b949be251a..048e44cd55d78 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -292,9 +292,9 @@ pub struct AsciiGenerator<'a, R> { impl<'a, R: Rng> Iterator for AsciiGenerator<'a, R> { fn next(&mut self) -> Option { 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) } } diff --git a/src/librustc/driver/mod.rs b/src/librustc/driver/mod.rs index ada65394e1923..f55fd78762c5d 100644 --- a/src/librustc/driver/mod.rs +++ b/src/librustc/driver/mod.rs @@ -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 diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index ec46e7f8592d3..c15148f75df22 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -214,7 +214,7 @@ pub fn rust_path() -> Vec { 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"); diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs index bb92043b1ea6a..b61596908e60a 100644 --- a/src/librustc/middle/borrowck/move_data.rs +++ b/src/librustc/middle/borrowck/move_data.rs @@ -25,6 +25,7 @@ use middle::dataflow::DataFlowContext; 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 AssignDataFlowOperator; 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 @@ impl MoveData { 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 + }); + } } } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index cd876113807a9..8cd840582ba99 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -701,17 +701,12 @@ impl<'a> Liveness<'a> { 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(); diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 808d894be4386..ffd29ffeb8fb4 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -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> { 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 } + }) } // 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); diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 9f4b11116dbb7..e4b28dc7aa7c2 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -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}; diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 11166f92b1cc2..783fdfa4aaec9 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -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()); diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 42c7a71bab84d..599b45aafe20d 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -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)> = diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index f48a93574e7e7..0304a1d690ef5 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -63,7 +63,7 @@ r##"
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index c6a6eb29addda..76e604ecfa287 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -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 @@ impl<'a> SourceCollector<'a> { }); 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()); diff --git a/src/librustrt/args.rs b/src/librustrt/args.rs index d6d4b18051bf3..09ae2b31f6368 100644 --- a/src/librustrt/args.rs +++ b/src/librustrt/args.rs @@ -123,8 +123,8 @@ mod imp { 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()); diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs index b4d9ac7efbebc..4a7ac97beed8d 100644 --- a/src/librustrt/c_str.rs +++ b/src/librustrt/c_str.rs @@ -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 @@ mod tests { } }); - 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 @@ mod tests { } }); - 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 @@ mod tests { #[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 @@ mod tests { 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); } diff --git a/src/librustuv/net.rs b/src/librustuv/net.rs index c8fb0f496dcb7..82693acb1e9dc 100644 --- a/src/librustuv/net.rs +++ b/src/librustuv/net.rs @@ -30,8 +30,8 @@ use uvll; /// 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::() } diff --git a/src/libserialize/base64.rs b/src/libserialize/base64.rs index 5a8759540c8b5..5c4da38989f11 100644 --- a/src/libserialize/base64.rs +++ b/src/libserialize/base64.rs @@ -42,13 +42,13 @@ pub static URL_SAFE: 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() { diff --git a/src/libserialize/ebml.rs b/src/libserialize/ebml.rs index 9ba2c2cd258ed..12c5a3493c17b 100644 --- a/src/libserialize/ebml.rs +++ b/src/libserialize/ebml.rs @@ -154,8 +154,6 @@ pub mod reader { } pub fn vuint_at(data: &[u8], start: uint) -> DecodeResult { - use std::mem::from_be32; - if data.len() - start < 4 { return vuint_at_slow(data, start); } @@ -185,7 +183,7 @@ pub mod reader { 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]; diff --git a/src/libserialize/hex.rs b/src/libserialize/hex.rs index 8ae3336c342b4..44d0606185345 100644 --- a/src/libserialize/hex.rs +++ b/src/libserialize/hex.rs @@ -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] { /** diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 9450f7798edcf..4f355502eb88d 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -535,7 +535,7 @@ mod test { #[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 @@ mod test { #[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()))); diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs index 20187a6dcde6b..a801dd0e7cb35 100644 --- a/src/libstd/io/fs.rs +++ b/src/libstd/io/fs.rs @@ -35,7 +35,7 @@ let path = Path::new("foo.txt"); // 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 @@ impl 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 @@ mod test { 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 @@ mod test { 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 @@ mod test { 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 @@ mod test { 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 @@ mod test { } 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 @@ mod test { 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 @@ mod test { 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 @@ mod test { 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); }) diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs index 71a967bb8dc5f..5eca5361835e3 100644 --- a/src/libstd/io/mem.rs +++ b/src/libstd/io/mem.rs @@ -474,7 +474,7 @@ mod test { #[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 @@ mod test { #[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()); } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index a7f84899a622e..d9755cdce1a4f 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -50,7 +50,7 @@ Some examples of obvious things you might want to do 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 @@ Some examples of obvious things you might want to do # // 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 @@ while still providing feedback about errors. The basic strategy: 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 @@ If you wanted to handle the error though you might write: # #![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 @@ mod tests { #[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); } } diff --git a/src/libstd/io/pipe.rs b/src/libstd/io/pipe.rs index 84d388c113630..a968f41a91563 100644 --- a/src/libstd/io/pipe.rs +++ b/src/libstd/io/pipe.rs @@ -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 { diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index c989dcc3d2945..e5a64f785ce96 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -22,7 +22,7 @@ about the stream or terminal to which it is attached. use std::io; let mut out = io::stdout(); -out.write(bytes!("Hello, world!")); +out.write(b"Hello, world!"); ``` */ diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs index 602a2240f3908..7301f9b08e9dc 100644 --- a/src/libstd/num/mod.rs +++ b/src/libstd/num/mod.rs @@ -22,7 +22,7 @@ use string::String; 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}; diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index 7d15893af241e..e55dc16589516 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -219,7 +219,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { 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 @@ pub trait GenericPath: Clone + GenericPathUnsafe { 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)) } } diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index 494428de3a5c4..d98cfb7d8eece 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -142,7 +142,7 @@ impl GenericPathUnsafe for Path { unsafe fn set_filename_unchecked(&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 @@ impl GenericPathUnsafe for Path { 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 @@ impl GenericPath for Path { 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 @@ impl GenericPath for Path { 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 @@ impl GenericPath for Path { } 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 @@ impl GenericPath for 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> { 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> { } 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> { } } -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 @@ mod tests { ) ) - 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 @@ mod tests { 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 @@ mod tests { 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 @@ mod tests { ) ) 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 @@ mod tests { ) 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 @@ mod tests { ) ) - 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 @@ mod tests { ); ) - 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 @@ mod tests { 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 @@ mod tests { 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 @@ mod tests { 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 @@ mod tests { 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 @@ mod tests { 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 @@ mod tests { #[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 @@ mod tests { 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 @@ mod tests { 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 @@ mod tests { ) ) - 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 @@ mod tests { ) ) - 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 @@ mod tests { 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 @@ mod tests { 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 @@ mod tests { 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::>(); - let exp: &[&[u8]] = [$(b!($($exp),*)),*]; + let exp: &[&[u8]] = [$($exp),*]; assert_eq!(comps.as_slice(), exp); let comps = path.components().rev().collect::>(); let exp = exp.iter().rev().map(|&x|x).collect::>(); @@ -1205,9 +1196,9 @@ mod tests { ) ) - 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 @@ mod tests { #[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::>>(); let exp: &[Option<&str>] = $exp; assert_eq!(comps.as_slice(), exp); @@ -1237,9 +1228,9 @@ mod tests { ) ) - 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 } diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 553c7af18cb26..4d6f8d0888f3e 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -1123,15 +1123,6 @@ mod tests { ) ) - 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 @@ mod tests { #[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 @@ mod tests { 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 @@ mod tests { #[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 @@ mod tests { 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 @@ mod tests { #[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 @@ mod tests { ) ) - 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 @@ mod tests { 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 @@ mod tests { 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 @@ mod tests { 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 @@ mod tests { 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 @@ mod tests { 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 @@ mod tests { 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 @@ mod tests { 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 @@ mod tests { 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 @@ mod tests { ) ) - 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 @@ mod tests { ) ) - 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 @@ mod tests { 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::>(); - let exp: &[&str] = $exp; - assert_eq!(comps.as_slice(), exp); - let comps = path.str_components().rev().map(|x|x.unwrap()) - .collect::>(); - let exp = exp.iter().rev().map(|&x|x).collect::>(); - 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 @@ mod tests { ) ) - 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 } diff --git a/src/libstd/task.rs b/src/libstd/task.rs index f543188af4295..0ead8fa6c0c83 100644 --- a/src/libstd/task.rs +++ b/src/libstd/task.rs @@ -8,71 +8,110 @@ // 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>, - /// A name for the task-to-be, for identification in failure messages - pub name: Option, - /// The size of the stack for the spawned task - pub stack_size: Option, - /// Task-local stdout - pub stdout: Option>, - /// Task-local stderr - pub stderr: Option>, +/// 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> = 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(): Send>, +pub struct TaskBuilder { + // A name for the task-to-be, for identification in failure messages + name: Option, + // The size of the stack for the spawned task + stack_size: Option, + // Task-local stdout + stdout: Option>, + // Task-local stderr + stderr: Option>, + // The mechanics of actually spawning the task (i.e.: green or native) + spawner: S, + // Optionally wrap the eventual task body + gen_body: Option 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 { + /// Generate the base configuration for spawning a task, off of which more + /// configuration methods can be chained. + pub fn new() -> TaskBuilder { 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 { - // 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 TaskBuilder { + /// Name the task-to-be. Currently the name is used for identification + /// only in failure messages. + pub fn named>(mut self, name: T) -> TaskBuilder { + 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 { + self.stack_size = Some(size); + self + } - rx + /// Redirect task-local stdout. + pub fn stdout(mut self, stdout: Box) -> TaskBuilder { + self.stdout = Some(stdout); + self } - /// Name the task-to-be. Currently the name is used for identification - /// only in failure messages. - pub fn named>(mut self, name: S) -> TaskBuilder { - self.opts.name = Some(name.into_maybe_owned()); + /// Redirect task-local stderr. + pub fn stderr(mut self, stderr: Box) -> TaskBuilder { + 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(self, spawner: T) -> TaskBuilder { + // 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 { self.gen_body = match self.gen_body.take() { Some(prev) => Some(proc(body) { wrapper(prev(body)) }), None => Some(wrapper) @@ -156,90 +222,80 @@ impl TaskBuilder { 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>):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 = 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(mut self, f: proc(): Send -> T) - -> Result> { - 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(self, f: proc():Send -> T) + -> Future>> { + // 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(self, f: proc():Send -> T) -> Result> { + 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(f: proc(): Send -> T) -> Result> { 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(f: proc():Send -> T) -> Future>> { + TaskBuilder::new().try_future(f) +} + /* Lifecycle functions */ @@ -273,9 +337,8 @@ pub fn with_task_name(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::).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::(); + fn avoid_copying_the_body(spawnfn: |v: proc():Send|) { + let (tx, rx) = channel::(); - 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::()); - assert_eq!(*e.move::().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::()); + assert_eq!(*e.move::().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::()); - assert_eq!(*e.move::().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::()); + assert_eq!(*e.move::().unwrap(), "owned string".to_string()); + } + Ok(()) => fail!() } - Ok(()) => fail!() } -} -#[test] -fn test_try_fail_message_any() { - match try(proc() { - fail!(box 413u16 as Box); - }) { - Err(e) => { - type T = Box; - assert!(e.is::()); - let any = e.move::().unwrap(); - assert!(any.is::()); - assert_eq!(*any.move::().unwrap(), 413u16); + #[test] + fn test_try_fail_message_any() { + match try(proc() { + fail!(box 413u16 as Box); + }) { + Err(e) => { + type T = Box; + assert!(e.is::()); + let any = e.move::().unwrap(); + assert!(any.is::()); + assert_eq!(*any.move::().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::() => {} + 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).try(proc() { + print!("Hello, world!"); + }).unwrap(); - match try(proc() { - fail!(Juju) - }) { - Err(ref e) if e.is::() => {} - 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. } diff --git a/src/libsync/lock.rs b/src/libsync/lock.rs index d7990068d5eb7..1fe8e8fc0db34 100644 --- a/src/libsync/lock.rs +++ b/src/libsync/lock.rs @@ -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 @@ mod tests { 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 diff --git a/src/libsyntax/ext/bytes.rs b/src/libsyntax/ext/bytes.rs index b87a25d4a44a2..ce13fa2a7c6ee 100644 --- a/src/libsyntax/ext/bytes.rs +++ b/src/libsyntax/ext/bytes.rs @@ -19,6 +19,14 @@ use ext::build::AstBuilder; pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> Box { + 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), diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs index b49c698486450..1a7063c495199 100644 --- a/src/libterm/terminfo/parm.rs +++ b/src/libterm/terminfo/parm.rs @@ -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 @@ mod test { } else { Number(97) }; - let res = expand(bytes!("%p1").iter().map(|x| *x).collect::>() + let res = expand("%p1".bytes().collect::>() .append(cap.as_bytes()).as_slice(), [p], vars); @@ -622,13 +622,13 @@ mod test { 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::>() + let res = expand("%{1}".bytes().collect::>() .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::>() + let res = expand("%{1}%{2}".bytes().collect::>() .append(cap.as_bytes()).as_slice(), [], vars); @@ -639,7 +639,7 @@ mod test { #[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 @@ mod test { #[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())); } } diff --git a/src/libterm/terminfo/parser/compiled.rs b/src/libterm/terminfo/parser/compiled.rs index b373753613d76..916342b67434e 100644 --- a/src/libterm/terminfo/parser/compiled.rs +++ b/src/libterm/terminfo/parser/compiled.rs @@ -315,10 +315,10 @@ pub fn parse(file: &mut io::Reader, longnames: bool) /// Create a dummy TermInfo struct for msys terminals pub fn msys_terminfo() -> Box { 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(), diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index e7c35fb59eee5..112ffd7c1a4a4 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -1049,14 +1049,13 @@ pub fn run_test(opts: &TestOpts, if nocapture { drop((stdout, stderr)); } else { - task.opts.stdout = Some(box stdout as Box); - task.opts.stderr = Some(box stderr as Box); + task = task.stdout(box stdout as Box); + task = task.stderr(box stderr as Box); } - 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)); }) diff --git a/src/libuuid/lib.rs b/src/libuuid/lib.rs index bace30e3f6ffd..b68b435da4bb0 100644 --- a/src/libuuid/lib.rs +++ b/src/libuuid/lib.rs @@ -209,8 +209,6 @@ impl 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 @@ impl 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 @@ impl Uuid { /// /// 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, diff --git a/src/snapshots.txt b/src/snapshots.txt index d528cb16e72dc..e46c99cf4f0dd 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -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 diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs index 03d91cf3aaa7a..14155d54d73cc 100644 --- a/src/test/bench/msgsend-pipes-shared.rs +++ b/src/test/bench/msgsend-pipes-shared.rs @@ -24,7 +24,6 @@ extern crate debug; use std::comm; use std::os; use std::task; -use std::task::TaskBuilder; use std::uint; fn move_out(_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"); diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs index 4de51c3ab4b8e..7ec2796b230a7 100644 --- a/src/test/bench/msgsend-pipes.rs +++ b/src/test/bench/msgsend-pipes.rs @@ -19,7 +19,6 @@ extern crate debug; use std::os; use std::task; -use std::task::TaskBuilder; use std::uint; fn move_out(_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"); diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs index 33853a91b7608..57a6d0e7c523d 100644 --- a/src/test/bench/shootout-pfib.rs +++ b/src/test/bench/shootout-pfib.rs @@ -24,7 +24,6 @@ extern crate time; 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(); } } diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs index c0ea6f8617d87..af51157bba564 100644 --- a/src/test/bench/sudoku.rs +++ b/src/test/bench/sudoku.rs @@ -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 index 0000000000000..c7fb646f585b9 --- /dev/null +++ b/src/test/compile-fail/borrowck-array-double-move.rs @@ -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 or the MIT license +// , 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(); +} + diff --git a/src/test/compile-fail/macros-nonfatal-errors.rs b/src/test/compile-fail/macros-nonfatal-errors.rs index df2c40657c814..5f8352d1e5229 100644 --- a/src/test/compile-fail/macros-nonfatal-errors.rs +++ b/src/test/compile-fail/macros-nonfatal-errors.rs @@ -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 diff --git a/src/test/compile-fail/syntax-extension-bytes-non-ascii-char-literal.rs b/src/test/compile-fail/syntax-extension-bytes-non-ascii-char-literal.rs index f5b4342ceb749..d03696cbbbcc4 100644 --- a/src/test/compile-fail/syntax-extension-bytes-non-ascii-char-literal.rs +++ b/src/test/compile-fail/syntax-extension-bytes-non-ascii-char-literal.rs @@ -10,4 +10,5 @@ fn main() { let vec = bytes!('λ'); //~ ERROR non-ascii char literal in bytes! + //~^ WARN `bytes!` is deprecated } diff --git a/src/test/compile-fail/syntax-extension-bytes-non-literal.rs b/src/test/compile-fail/syntax-extension-bytes-non-literal.rs index 281a5630f82c9..3a2e104818fd2 100644 --- a/src/test/compile-fail/syntax-extension-bytes-non-literal.rs +++ b/src/test/compile-fail/syntax-extension-bytes-non-literal.rs @@ -10,4 +10,5 @@ fn main() { let vec = bytes!(foo); //~ ERROR non-literal in bytes! + //~^ WARN `bytes!` is deprecated } diff --git a/src/test/compile-fail/syntax-extension-bytes-too-large-integer-literal.rs b/src/test/compile-fail/syntax-extension-bytes-too-large-integer-literal.rs index 25688d7d17ab4..8e7c6147758ca 100644 --- a/src/test/compile-fail/syntax-extension-bytes-too-large-integer-literal.rs +++ b/src/test/compile-fail/syntax-extension-bytes-too-large-integer-literal.rs @@ -10,4 +10,5 @@ fn main() { let vec = bytes!(1024); //~ ERROR too large integer literal in bytes! + //~^ WARN `bytes!` is deprecated } diff --git a/src/test/compile-fail/syntax-extension-bytes-too-large-u8-literal.rs b/src/test/compile-fail/syntax-extension-bytes-too-large-u8-literal.rs index d1c8a2c091304..1a9aa3753eec7 100644 --- a/src/test/compile-fail/syntax-extension-bytes-too-large-u8-literal.rs +++ b/src/test/compile-fail/syntax-extension-bytes-too-large-u8-literal.rs @@ -10,4 +10,5 @@ fn main() { let vec = bytes!(1024u8); //~ ERROR too large u8 literal in bytes! + //~^ WARN `bytes!` is deprecated } diff --git a/src/test/compile-fail/syntax-extension-bytes-too-small-integer-literal.rs b/src/test/compile-fail/syntax-extension-bytes-too-small-integer-literal.rs index ef45ea06003d5..c2d4973594371 100644 --- a/src/test/compile-fail/syntax-extension-bytes-too-small-integer-literal.rs +++ b/src/test/compile-fail/syntax-extension-bytes-too-small-integer-literal.rs @@ -10,4 +10,5 @@ fn main() { let vec = bytes!(-1024); //~ ERROR non-literal in bytes + //~^ WARN `bytes!` is deprecated } diff --git a/src/test/compile-fail/syntax-extension-bytes-too-small-u8-literal.rs b/src/test/compile-fail/syntax-extension-bytes-too-small-u8-literal.rs index b8ba73559aa74..ac33ffb60e294 100644 --- a/src/test/compile-fail/syntax-extension-bytes-too-small-u8-literal.rs +++ b/src/test/compile-fail/syntax-extension-bytes-too-small-u8-literal.rs @@ -10,4 +10,5 @@ fn main() { let vec = bytes!(-1024u8); //~ ERROR non-literal in bytes + //~^ WARN `bytes!` is deprecated } diff --git a/src/test/compile-fail/syntax-extension-bytes-unsupported-literal.rs b/src/test/compile-fail/syntax-extension-bytes-unsupported-literal.rs index 142566fe8ab78..f6b3659354c5b 100644 --- a/src/test/compile-fail/syntax-extension-bytes-unsupported-literal.rs +++ b/src/test/compile-fail/syntax-extension-bytes-unsupported-literal.rs @@ -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 index 0000000000000..16c7dcc34ff60 --- /dev/null +++ b/src/test/debuginfo/issue14411.rs @@ -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 or the MIT license +// , 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) { + 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 index 0000000000000..7fa88a7653ac4 --- /dev/null +++ b/src/test/run-pass/issue-14865.rs @@ -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 or the MIT license +// , 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 index 0000000000000..045d3cc0458f7 --- /dev/null +++ b/src/test/run-pass/issue-14958.rs @@ -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 or the MIT license +// , 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); +} diff --git a/src/test/run-pass/issue-2190-1.rs b/src/test/run-pass/issue-2190-1.rs index f1217be3484fe..4ff735708b5ab 100644 --- a/src/test/run-pass/issue-2190-1.rs +++ b/src/test/run-pass/issue-2190-1.rs @@ -13,9 +13,7 @@ use std::task::TaskBuilder; 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 { diff --git a/src/test/run-pass/issue-4333.rs b/src/test/run-pass/issue-4333.rs index 6fb66cd3b1580..fd67b767104d5 100644 --- a/src/test/run-pass/issue-4333.rs +++ b/src/test/run-pass/issue-4333.rs @@ -12,5 +12,5 @@ use std::io; pub fn main() { let stdout = &mut io::stdout() as &mut io::Writer; - stdout.write(bytes!("Hello!")); + stdout.write(b"Hello!"); } diff --git a/src/test/run-pass/task-comm-12.rs b/src/test/run-pass/task-comm-12.rs index a78bbefed44db..851f87adfc20d 100644 --- a/src/test/run-pass/task-comm-12.rs +++ b/src/test/run-pass/task-comm-12.rs @@ -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 start(_task_number: int) { println!("Started / Finished task."); } 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."); } diff --git a/src/test/run-pass/task-comm-3.rs b/src/test/run-pass/task-comm-3.rs index 217bab5c1dea6..cd31d15db1092 100644 --- a/src/test/run-pass/task-comm-3.rs +++ b/src/test/run-pass/task-comm-3.rs @@ -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); diff --git a/src/test/run-pass/task-comm-9.rs b/src/test/run-pass/task-comm-9.rs index ab6498c00279b..a46b4513c5dee 100644 --- a/src/test/run-pass/task-comm-9.rs +++ b/src/test/run-pass/task-comm-9.rs @@ -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 index 0000000000000..6a71f9df6e45e --- /dev/null +++ b/src/test/run-pass/task-stderr.rs @@ -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 or the MIT license +// , 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).try(proc() -> () { + fail!("Hello, world!") + }); + assert!(res.is_err()); + + let output = reader.read_to_str().unwrap(); + assert!(output.as_slice().contains("Hello, world!")); +} diff --git a/src/test/run-pass/tcp-stress.rs b/src/test/run-pass/tcp-stress.rs index 9c4716e5f4d38..99bf247229e05 100644 --- a/src/test/run-pass/tcp-stress.rs +++ b/src/test/run-pass/tcp-stress.rs @@ -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) { diff --git a/src/test/run-pass/tempfile.rs b/src/test/run-pass/tempfile.rs index 316d1facb18ff..4355bf4127fc4 100644 --- a/src/test/run-pass/tempfile.rs +++ b/src/test/run-pass/tempfile.rs @@ -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()); diff --git a/src/test/run-pass/trait-coercion.rs b/src/test/run-pass/trait-coercion.rs index 1d229a8ae8361..55beebbf2bc57 100644 --- a/src/test/run-pass/trait-coercion.rs +++ b/src/test/run-pass/trait-coercion.rs @@ -26,7 +26,7 @@ impl Trait for Struct { } fn foo(mut a: Box) { - a.write(bytes!("Hello\n")); + a.write(b"Hello\n"); } pub fn main() { diff --git a/src/test/run-pass/yield.rs b/src/test/run-pass/yield.rs index 2662a6c6568b9..89d204dcecbdb 100644 --- a/src/test/run-pass/yield.rs +++ b/src/test/run-pass/yield.rs @@ -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() { diff --git a/src/test/run-pass/yield1.rs b/src/test/run-pass/yield1.rs index 8c5504725bb48..d882b1abd295d 100644 --- a/src/test/run-pass/yield1.rs +++ b/src/test/run-pass/yield1.rs @@ -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"); }