Merge remote-tracking branch 'mozilla/master'
Conflicts: src/libextra/test.rs src/libstd/at_vec.rs src/libstd/cleanup.rs src/libstd/rt/comm.rs src/libstd/rt/global_heap.rs src/libstd/task/spawn.rs src/libstd/unstable/lang.rs src/libstd/vec.rs src/rt/rustrt.def.in src/test/run-pass/extern-pub.rs
This commit is contained in:
commit
1098d6980b
765 changed files with 23500 additions and 17316 deletions
|
|
@ -15,8 +15,8 @@
|
|||
#[no_core]; // XXX: Remove after snapshot
|
||||
#[no_std];
|
||||
|
||||
extern mod core(name = "std", vers = "0.7-pre");
|
||||
extern mod extra(name = "extra", vers = "0.7-pre");
|
||||
extern mod core(name = "std", vers = "0.7");
|
||||
extern mod extra(name = "extra", vers = "0.7");
|
||||
|
||||
use core::prelude::*;
|
||||
use core::*;
|
||||
|
|
@ -75,7 +75,7 @@ pub fn parse_config(args: ~[~str]) -> config {
|
|||
];
|
||||
|
||||
assert!(!args.is_empty());
|
||||
let args_ = vec::tail(args);
|
||||
let args_ = args.tail();
|
||||
let matches =
|
||||
&match getopts::getopts(args_, opts) {
|
||||
Ok(m) => m,
|
||||
|
|
@ -208,7 +208,8 @@ pub fn make_tests(config: &config) -> ~[test::TestDescAndFn] {
|
|||
debug!("making tests from %s",
|
||||
config.src_base.to_str());
|
||||
let mut tests = ~[];
|
||||
for os::list_dir_path(&config.src_base).each |file| {
|
||||
let dirs = os::list_dir_path(&config.src_base);
|
||||
for dirs.iter().advance |file| {
|
||||
let file = copy *file;
|
||||
debug!("inspecting file %s", file.to_str());
|
||||
if is_test(config, file) {
|
||||
|
|
@ -230,11 +231,11 @@ pub fn is_test(config: &config, testfile: &Path) -> bool {
|
|||
|
||||
let mut valid = false;
|
||||
|
||||
for valid_extensions.each |ext| {
|
||||
for valid_extensions.iter().advance |ext| {
|
||||
if name.ends_with(*ext) { valid = true; }
|
||||
}
|
||||
|
||||
for invalid_prefixes.each |pre| {
|
||||
for invalid_prefixes.iter().advance |pre| {
|
||||
if name.starts_with(*pre) { valid = false; }
|
||||
}
|
||||
|
||||
|
|
@ -253,9 +254,17 @@ pub fn make_test(config: &config, testfile: &Path) -> test::TestDescAndFn {
|
|||
}
|
||||
|
||||
pub fn make_test_name(config: &config, testfile: &Path) -> test::TestName {
|
||||
|
||||
// Try to elide redundant long paths
|
||||
fn shorten(path: &Path) -> ~str {
|
||||
let filename = path.filename();
|
||||
let dir = path.pop().filename();
|
||||
fmt!("%s/%s", dir.get_or_default(~""), filename.get_or_default(~""))
|
||||
}
|
||||
|
||||
test::DynTestName(fmt!("[%s] %s",
|
||||
mode_str(config.mode),
|
||||
testfile.to_str()))
|
||||
shorten(testfile)))
|
||||
}
|
||||
|
||||
pub fn make_test_closure(config: &config, testfile: &Path) -> test::TestFn {
|
||||
|
|
@ -21,7 +21,7 @@ pub fn load_errors(testfile: &Path) -> ~[ExpectedError] {
|
|||
let mut line_num = 1u;
|
||||
while !rdr.eof() {
|
||||
let ln = rdr.read_line();
|
||||
error_patterns += parse_expected(line_num, ln);
|
||||
error_patterns.push_all_move(parse_expected(line_num, ln));
|
||||
line_num += 1u;
|
||||
}
|
||||
return error_patterns;
|
||||
|
|
|
|||
|
|
@ -226,8 +226,8 @@ actual:\n\
|
|||
~"-L", config.build_base.to_str(),
|
||||
~"-L",
|
||||
aux_output_dir_name(config, testfile).to_str()];
|
||||
args += split_maybe_args(&config.rustcflags);
|
||||
args += split_maybe_args(&props.compile_flags);
|
||||
args.push_all_move(split_maybe_args(&config.rustcflags));
|
||||
args.push_all_move(split_maybe_args(&props.compile_flags));
|
||||
return ProcArgs {prog: config.rustc_path.to_str(), args: args};
|
||||
}
|
||||
}
|
||||
|
|
@ -321,13 +321,12 @@ fn check_error_patterns(props: &TestProps,
|
|||
if done { return; }
|
||||
|
||||
let missing_patterns =
|
||||
vec::slice(props.error_patterns, next_err_idx,
|
||||
props.error_patterns.len());
|
||||
props.error_patterns.slice(next_err_idx, props.error_patterns.len());
|
||||
if missing_patterns.len() == 1u {
|
||||
fatal_ProcRes(fmt!("error pattern '%s' not found!",
|
||||
missing_patterns[0]), ProcRes);
|
||||
} else {
|
||||
for missing_patterns.each |pattern| {
|
||||
for missing_patterns.iter().advance |pattern| {
|
||||
error(fmt!("error pattern '%s' not found!", *pattern));
|
||||
}
|
||||
fatal_ProcRes(~"multiple error patterns not found", ProcRes);
|
||||
|
|
@ -346,9 +345,9 @@ fn check_expected_errors(expected_errors: ~[errors::ExpectedError],
|
|||
fatal(~"process did not return an error status");
|
||||
}
|
||||
|
||||
let prefixes = vec::map(expected_errors, |ee| {
|
||||
let prefixes = expected_errors.iter().transform(|ee| {
|
||||
fmt!("%s:%u:", testfile.to_str(), ee.line)
|
||||
});
|
||||
}).collect::<~[~str]>();
|
||||
|
||||
// Scan and extract our error/warning messages,
|
||||
// which look like:
|
||||
|
|
@ -358,7 +357,7 @@ fn check_expected_errors(expected_errors: ~[errors::ExpectedError],
|
|||
// is the ending point, and * represents ANSI color codes.
|
||||
for ProcRes.stderr.line_iter().advance |line| {
|
||||
let mut was_expected = false;
|
||||
for vec::eachi(expected_errors) |i, ee| {
|
||||
for expected_errors.iter().enumerate().advance |(i, ee)| {
|
||||
if !found_flags[i] {
|
||||
debug!("prefix=%s ee.kind=%s ee.msg=%s line=%s",
|
||||
prefixes[i], ee.kind, ee.msg, line);
|
||||
|
|
@ -529,7 +528,7 @@ fn compose_and_run_compiler(
|
|||
let extra_link_args = ~[~"-L",
|
||||
aux_output_dir_name(config, testfile).to_str()];
|
||||
|
||||
for vec::each(props.aux_builds) |rel_ab| {
|
||||
for props.aux_builds.iter().advance |rel_ab| {
|
||||
let abs_ab = config.aux_base.push_rel(&Path(*rel_ab));
|
||||
let aux_args =
|
||||
make_compile_args(config, props, ~[~"--lib"] + extra_link_args,
|
||||
|
|
@ -582,8 +581,8 @@ fn make_compile_args(config: &config, props: &TestProps, extras: ~[~str],
|
|||
~"-o", xform(config, testfile).to_str(),
|
||||
~"-L", config.build_base.to_str()]
|
||||
+ extras;
|
||||
args += split_maybe_args(&config.rustcflags);
|
||||
args += split_maybe_args(&props.compile_flags);
|
||||
args.push_all_move(split_maybe_args(&config.rustcflags));
|
||||
args.push_all_move(split_maybe_args(&props.compile_flags));
|
||||
return ProcArgs {prog: config.rustc_path.to_str(), args: args};
|
||||
}
|
||||
|
||||
|
|
@ -757,7 +756,7 @@ fn _arm_exec_compiled_test(config: &config, props: &TestProps,
|
|||
runargs.push(fmt!("%s", config.adb_test_dir));
|
||||
runargs.push(fmt!("%s", prog_short));
|
||||
|
||||
for args.args.each |tv| {
|
||||
for args.args.iter().advance |tv| {
|
||||
runargs.push(tv.to_owned());
|
||||
}
|
||||
|
||||
|
|
@ -822,7 +821,8 @@ fn _dummy_exec_compiled_test(config: &config, props: &TestProps,
|
|||
fn _arm_push_aux_shared_library(config: &config, testfile: &Path) {
|
||||
let tstr = aux_output_dir_name(config, testfile).to_str();
|
||||
|
||||
for os::list_dir_path(&Path(tstr)).each |file| {
|
||||
let dirs = os::list_dir_path(&Path(tstr));
|
||||
for dirs.iter().advance |file| {
|
||||
|
||||
if (file.filetype() == Some(~".so")) {
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#[no_core];
|
||||
#[no_std];
|
||||
|
||||
extern mod core(name = "std", vers = "0.7-pre");
|
||||
extern mod core(name = "std", vers = "0.7");
|
||||
|
||||
#[cfg(rustpkg)]
|
||||
extern mod this(name = "rustpkg");
|
||||
|
|
|
|||
|
|
@ -17,16 +17,17 @@ then
|
|||
|
||||
L_RET=1
|
||||
L_COUNT=0
|
||||
cd $PATH
|
||||
while [ $L_RET -eq 1 ]
|
||||
do
|
||||
LD_LIBRARY_PATH=$PATH $PATH/$RUN $@ 1>$PATH/$RUN.stdout 2>$PATH/$RUN.stderr
|
||||
TEST_EXEC_ENV=22 LD_LIBRARY_PATH=$PATH $PATH/$RUN $@ 1>$PATH/$RUN.stdout 2>$PATH/$RUN.stderr
|
||||
L_RET=$?
|
||||
if [ $L_COUNT -gt 0 ]
|
||||
then
|
||||
/system/bin/sleep $WAIT
|
||||
/system/bin/sync
|
||||
fi
|
||||
L_COUNT=`expr $L_COUNT+1`
|
||||
L_COUNT=$((L_COUNT+1))
|
||||
done
|
||||
|
||||
echo $L_RET > $PATH/$RUN.exitcode
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ i = 0
|
|||
for t in stage2_tests:
|
||||
p = os.path.join("test", "run-pass", t)
|
||||
p = p.replace("\\", "\\\\")
|
||||
d.write(" out.write_str(~\"run-pass [stage2]: %s\\n\");\n" % p)
|
||||
d.write(" out.write_str(\"run-pass [stage2]: %s\\n\");\n" % p)
|
||||
d.write(" t_%d::main();\n" % i)
|
||||
i += 1
|
||||
d.write("}\n")
|
||||
|
|
|
|||
|
|
@ -8,3 +8,4 @@
|
|||
--regex-rust=/[ \t]*static[ \t]+([a-zA-Z0-9_]+)/\1/m,consts/
|
||||
--regex-rust=/[ \t]*trait[ \t]+([a-zA-Z0-9_]+)/\1/m,traits/
|
||||
--regex-rust=/[ \t]*impl[ \t]+([a-zA-Z0-9_]+)/\1/m,impls/
|
||||
--regex-rust=/[ \t]*macro_rules![ \t]+([a-zA-Z0-9_]+)/\1/m,macros/
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<!ENTITY rustIdent "[a-zA-Z_][a-zA-Z_0-9]*">
|
||||
<!ENTITY rustIntSuf "([iu](8|16|32|64)?)?">
|
||||
]>
|
||||
<language name="Rust" version="0.7-pre" kateversion="2.4" section="Sources" extensions="*.rs;*.rc" mimetype="text/x-rust" priority="15">
|
||||
<language name="Rust" version="0.7" kateversion="2.4" section="Sources" extensions="*.rs;*.rc" mimetype="text/x-rust" priority="15">
|
||||
<highlighting>
|
||||
<list name="fn">
|
||||
<item> fn </item>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#define CFG_VERSION GetEnv("CFG_VERSION")
|
||||
#define CFG_VERSION_WIN GetEnv("CFG_VERSION_WIN")
|
||||
|
||||
[Setup]
|
||||
|
||||
|
|
@ -8,7 +9,7 @@ AppVersion={#CFG_VERSION}
|
|||
AppCopyright=Copyright (C) 2006-2013 Mozilla Foundation, MIT license
|
||||
AppPublisher=Mozilla Foundation
|
||||
AppPublisherURL=http://www.rust-lang.org
|
||||
VersionInfoVersion={#CFG_VERSION}
|
||||
VersionInfoVersion={#CFG_VERSION_WIN}
|
||||
LicenseFile=LICENSE.txt
|
||||
|
||||
DisableWelcomePage=true
|
||||
|
|
|
|||
|
|
@ -122,14 +122,14 @@ def ch_prefix(ix):
|
|||
|
||||
def emit_bsearch_range_table(f):
|
||||
f.write("""
|
||||
pure fn bsearch_range_table(c: char, r: &[(char,char)]) -> bool {
|
||||
use cmp::{EQ, LT, GT};
|
||||
use vec::bsearch;
|
||||
fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
|
||||
use cmp::{Equal, Less, Greater};
|
||||
use vec::ImmutableVector;
|
||||
use option::None;
|
||||
(do bsearch(r) |&(lo,hi)| {
|
||||
if lo <= c && c <= hi { EQ }
|
||||
else if hi < c { LT }
|
||||
else { GT }
|
||||
(do r.bsearch |&(lo,hi)| {
|
||||
if lo <= c && c <= hi { Equal }
|
||||
else if hi < c { Less }
|
||||
else { Greater }
|
||||
}) != None
|
||||
}\n\n
|
||||
""");
|
||||
|
|
@ -140,7 +140,7 @@ def emit_property_module(f, mod, tbl):
|
|||
keys.sort()
|
||||
emit_bsearch_range_table(f);
|
||||
for cat in keys:
|
||||
f.write(" const %s_table : &[(char,char)] = &[\n" % cat)
|
||||
f.write(" static %s_table : &'static [(char,char)] = &[\n" % cat)
|
||||
ix = 0
|
||||
for pair in tbl[cat]:
|
||||
f.write(ch_prefix(ix))
|
||||
|
|
@ -148,7 +148,7 @@ def emit_property_module(f, mod, tbl):
|
|||
ix += 1
|
||||
f.write("\n ];\n\n")
|
||||
|
||||
f.write(" pub pure fn %s(c: char) -> bool {\n" % cat)
|
||||
f.write(" pub fn %s(c: char) -> bool {\n" % cat)
|
||||
f.write(" bsearch_range_table(c, %s_table)\n" % cat)
|
||||
f.write(" }\n\n")
|
||||
f.write("}\n")
|
||||
|
|
@ -159,7 +159,7 @@ def emit_property_module_old(f, mod, tbl):
|
|||
keys = tbl.keys()
|
||||
keys.sort()
|
||||
for cat in keys:
|
||||
f.write(" pure fn %s(c: char) -> bool {\n" % cat)
|
||||
f.write(" fn %s(c: char) -> bool {\n" % cat)
|
||||
f.write(" ret alt c {\n")
|
||||
prefix = ' '
|
||||
for pair in tbl[cat]:
|
||||
|
|
@ -236,8 +236,22 @@ rf = open(r, "w")
|
|||
|
||||
(canon_decomp, compat_decomp, gencats) = load_unicode_data("UnicodeData.txt")
|
||||
|
||||
# Explain that the source code was generated by this script.
|
||||
rf.write('// The following code was generated by "src/etc/unicode.py"\n\n')
|
||||
# Preamble
|
||||
rf.write('''// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// The following code was generated by "src/etc/unicode.py"
|
||||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
''')
|
||||
|
||||
emit_property_module(rf, "general_category", gencats)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
" Language: Rust
|
||||
" Maintainer: Patrick Walton <pcwalton@mozilla.com>
|
||||
" Maintainer: Ben Blum <bblum@cs.cmu.edu>
|
||||
" Last Change: 2012 Dec 25
|
||||
" Last Change: 2013 Jun 14
|
||||
|
||||
if version < 600
|
||||
syntax clear
|
||||
|
|
@ -13,13 +13,16 @@ endif
|
|||
syn keyword rustConditional match if else
|
||||
syn keyword rustOperator as
|
||||
|
||||
syn keyword rustKeyword break copy do drop extern
|
||||
syn match rustAssert "\<assert\(\w\)*!"
|
||||
syn match rustFail "\<fail\(\w\)*!"
|
||||
syn keyword rustKeyword break copy do extern
|
||||
syn keyword rustKeyword for if impl let log
|
||||
syn keyword rustKeyword copy do extern
|
||||
syn keyword rustKeyword for impl let log
|
||||
syn keyword rustKeyword loop mod once priv pub
|
||||
syn keyword rustKeyword return
|
||||
syn keyword rustKeyword unsafe use while
|
||||
syn keyword rustKeyword unsafe while
|
||||
syn keyword rustKeyword use nextgroup=rustModPath skipwhite
|
||||
" FIXME: Scoped impl's name is also fallen in this category
|
||||
syn keyword rustKeyword mod trait struct enum type nextgroup=rustIdentifier skipwhite
|
||||
syn keyword rustKeyword fn nextgroup=rustFuncName skipwhite
|
||||
|
|
@ -45,7 +48,8 @@ syn keyword rustType c_longlong c_ulonglong intptr_t uintptr_t
|
|||
syn keyword rustType off_t dev_t ino_t pid_t mode_t ssize_t
|
||||
|
||||
syn keyword rustTrait Const Copy Send Owned Sized " inherent traits
|
||||
syn keyword rustTrait Eq Ord Num Ptr
|
||||
syn keyword rustTrait Clone Decodable Encodable IterBytes Rand ToStr
|
||||
syn keyword rustTrait Eq Ord TotalEq TotalOrd Num Ptr
|
||||
syn keyword rustTrait Drop Add Sub Mul Quot Rem Neg BitAnd BitOr
|
||||
syn keyword rustTrait BitXor Shl Shr Index
|
||||
|
||||
|
|
@ -72,19 +76,21 @@ syn keyword rustConstant STDIN_FILENO STDOUT_FILENO STDERR_FILENO
|
|||
" If foo::bar changes to foo.bar, change this ("::" to "\.").
|
||||
" If foo::bar changes to Foo::bar, change this (first "\w" to "\u").
|
||||
syn match rustModPath "\w\(\w\)*::[^<]"he=e-3,me=e-3
|
||||
syn match rustModPath "\w\(\w\)*" contained " only for 'use path;'
|
||||
syn match rustModPathSep "::"
|
||||
|
||||
syn match rustFuncCall "\w\(\w\)*("he=e-1,me=e-1
|
||||
syn match rustFuncCall "\w\(\w\)*::<"he=e-3,me=e-3 " foo::<T>();
|
||||
|
||||
syn match rustMacro '\w\(\w\)*!'
|
||||
syn match rustMacro '#\w\(\w\)*'
|
||||
syn match rustMacro '\w\(\w\)*!' contains=rustAssert,rustFail
|
||||
syn match rustMacro '#\w\(\w\)*' contains=rustAssert,rustFail
|
||||
|
||||
syn match rustFormat display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlLjzt]\|ll\|hh\)\=\([aAbdiuoxXDOUfFeEgGcCsSpn?]\|\[\^\=.[^]]*\]\)" contained
|
||||
syn match rustFormat display "%%" contained
|
||||
syn region rustString start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=rustTodo,rustFormat
|
||||
|
||||
syn region rustAttribute start="#\[" end="\]" contains=rustString
|
||||
syn region rustAttribute start="#\[" end="\]" contains=rustString,rustDeriving
|
||||
syn region rustDeriving start="deriving(" end=")" contains=rustTrait
|
||||
|
||||
" Number literals
|
||||
syn match rustNumber display "\<[0-9][0-9_]*\>"
|
||||
|
|
@ -137,17 +143,24 @@ hi def link rustConditional Conditional
|
|||
hi def link rustIdentifier Identifier
|
||||
hi def link rustModPath Include
|
||||
hi def link rustFuncName Function
|
||||
hi def link rustFuncCall Function
|
||||
hi def link rustCommentDoc SpecialComment
|
||||
hi def link rustComment Comment
|
||||
hi def link rustMacro Macro
|
||||
hi def link rustType Type
|
||||
hi def link rustTodo Todo
|
||||
hi def link rustAttribute PreProc
|
||||
hi def link rustDeriving PreProc
|
||||
hi def link rustStorage StorageClass
|
||||
hi def link rustLifetime Special
|
||||
|
||||
" Other Suggestions:
|
||||
" hi rustAttribute ctermfg=cyan
|
||||
" hi rustDeriving ctermfg=cyan
|
||||
" hi rustAssert ctermfg=yellow
|
||||
" hi rustFail ctermfg=red
|
||||
" hi rustMacro ctermfg=magenta
|
||||
" hi rustModPathSep ctermfg=grey
|
||||
|
||||
syn sync minlines=200
|
||||
syn sync maxlines=500
|
||||
|
|
|
|||
|
|
@ -29,36 +29,30 @@ _rustc_opts_switches=(
|
|||
--target'[Target triple cpu-manufacturer-kernel\[-os\] to compile]'
|
||||
--target-feature'[Target specific attributes (llc -mattr=help for detail)]'
|
||||
--android-cross-path'[The path to the Android NDK]'
|
||||
{-W,--warn}'[Set lint warnings]'
|
||||
{-A,--allow}'[Set lint allowed]'
|
||||
{-D,--deny}'[Set lint denied]'
|
||||
{-F,--forbid}'[Set lint forbidden]'
|
||||
-Z'[Set internal debugging options]'
|
||||
{-v,--version}'[Print version info and exit]'
|
||||
)
|
||||
|
||||
_rustc_opts_lint=(
|
||||
'path-statement:path statements with no effect'
|
||||
'deprecated-pattern:warn about deprecated uses of pattern bindings'
|
||||
'non-implicitly-copyable-typarams:passing non implicitly copyable types as copy type params'
|
||||
'missing-trait-doc:detects missing documentation for traits'
|
||||
'missing-struct-doc:detects missing documentation for structs'
|
||||
'ctypes:proper use of core::libc types in foreign modules'
|
||||
'implicit-copies:implicit copies of non implicitly copyable data'
|
||||
"unused-mut:detect mut variables which don't need to be mutable"
|
||||
'unused-imports:imports that are never used'
|
||||
'heap-memory:use of any (~ type or @ type) heap memory'
|
||||
'default-methods:allow default methods'
|
||||
'unused-variable:detect variables which are not used in any way'
|
||||
'dead-assignment:detect assignments that will never be read'
|
||||
'unrecognized-lint:unrecognized lint attribute'
|
||||
'type-limits:comparisons made useless by limits of the types involved'
|
||||
'unused-unsafe:unnecessary use of an `unsafe` block'
|
||||
'while-true:suggest using loop { } instead of while(true) { }'
|
||||
'non-camel-case-types:types, variants and traits should have camel case names'
|
||||
'managed-heap-memory:use of managed (@ type) heap memory'
|
||||
'unnecessary-allocation:detects unnecessary allocations that can be eliminated'
|
||||
'owned-heap-memory:use of owned (~ type) heap memory'
|
||||
'path-statement[path statements with no effect]'
|
||||
'deprecated-pattern[warn about deprecated uses of pattern bindings]'
|
||||
'non-implicitly-copyable-typarams[passing non implicitly copyable types as copy type params]'
|
||||
'missing-trait-doc[detects missing documentation for traits]'
|
||||
'missing-struct-doc[detects missing documentation for structs]'
|
||||
'ctypes[proper use of core::libc types in foreign modules]'
|
||||
'implicit-copies[implicit copies of non implicitly copyable data]'
|
||||
"unused-mut[detect mut variables which don't need to be mutable]"
|
||||
'unused-imports[imports that are never used]'
|
||||
'heap-memory[use of any (~ type or @ type) heap memory]'
|
||||
'default-methods[allow default methods]'
|
||||
'unused-variable[detect variables which are not used in any way]'
|
||||
'dead-assignment[detect assignments that will never be read]'
|
||||
'unrecognized-lint[unrecognized lint attribute]'
|
||||
'type-limits[comparisons made useless by limits of the types involved]'
|
||||
'unused-unsafe[unnecessary use of an `unsafe` block]'
|
||||
'while-true[suggest using loop { } instead of while(true) { }]'
|
||||
'non-camel-case-types[types, variants and traits should have camel case names]'
|
||||
'managed-heap-memory[use of managed (@ type) heap memory]'
|
||||
'unnecessary-allocation[detects unnecessary allocations that can be eliminated]'
|
||||
'owned-heap-memory[use of owned (~ type) heap memory]'
|
||||
)
|
||||
|
||||
_rustc_opts_debug=(
|
||||
|
|
@ -90,13 +84,20 @@ _rustc_opts_debug=(
|
|||
'lint-llvm:Run the LLVM lint pass on the pre-optimization IR'
|
||||
)
|
||||
|
||||
_rustc() {
|
||||
case $words[2] in
|
||||
-[WADF]) _describe 'options' _rustc_opts_lint ;;
|
||||
-Z) _describe 'options' _rustc_opts_debug ;;
|
||||
-) _arguments -s -w : "$_rustc_opts_switches[@]" ;;
|
||||
*) _files -g "*.rs" ;;
|
||||
esac
|
||||
_rustc_opts_fun_lint(){
|
||||
_values -s , 'options' \
|
||||
"$_rustc_opts_lint[@]"
|
||||
}
|
||||
|
||||
_rustc "$@"
|
||||
_rustc_opts_fun_debug(){
|
||||
_describe 'options' _rustc_opts_debug
|
||||
}
|
||||
|
||||
_arguments -s : \
|
||||
'(-W --warn)'{-W,--warn}'[Set lint warnings]:lint options:_rustc_opts_fun_lint' \
|
||||
'(-A --allow)'{-A,--allow}'[Set lint allowed]:lint options:_rustc_opts_fun_lint' \
|
||||
'(-D --deny)'{-D,--deny}'[Set lint denied]:lint options:_rustc_opts_fun_lint' \
|
||||
'(-F --forbid)'{-F,--forbid}'[Set lint forbidden]:lint options:_rustc_opts_fun_lint' \
|
||||
'*-Z[Set internal debugging options]:debug options:_rustc_opts_fun_debug' \
|
||||
"$_rustc_opts_switches[@]" \
|
||||
'*::files:_files -g "*.rs"'
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
* ~~~ {.rust}
|
||||
* extern mod std;
|
||||
* use std::arc;
|
||||
* use extra::arc;
|
||||
* let numbers=vec::from_fn(100, |ind| (ind as float)*rand::random());
|
||||
* let shared_numbers=arc::ARC(numbers);
|
||||
*
|
||||
|
|
@ -39,15 +39,14 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use sync;
|
||||
use sync::{Mutex, mutex_with_condvars, RWlock, rwlock_with_condvars};
|
||||
|
||||
use core::cast;
|
||||
use core::unstable::sync::UnsafeAtomicRcBox;
|
||||
use core::task;
|
||||
use core::borrow;
|
||||
use std::cast;
|
||||
use std::unstable::sync::UnsafeAtomicRcBox;
|
||||
use std::task;
|
||||
use std::borrow;
|
||||
|
||||
/// As sync::condvar, a mechanism for unlock-and-descheduling and signaling.
|
||||
pub struct Condvar<'self> {
|
||||
|
|
@ -112,7 +111,7 @@ impl<'self> Condvar<'self> {
|
|||
pub struct ARC<T> { x: UnsafeAtomicRcBox<T> }
|
||||
|
||||
/// Create an atomically reference counted wrapper.
|
||||
pub fn ARC<T:Const + Owned>(data: T) -> ARC<T> {
|
||||
pub fn ARC<T:Freeze + Send>(data: T) -> ARC<T> {
|
||||
ARC { x: UnsafeAtomicRcBox::new(data) }
|
||||
}
|
||||
|
||||
|
|
@ -120,7 +119,7 @@ pub fn ARC<T:Const + Owned>(data: T) -> ARC<T> {
|
|||
* Access the underlying data in an atomically reference counted
|
||||
* wrapper.
|
||||
*/
|
||||
impl<T:Const+Owned> ARC<T> {
|
||||
impl<T:Freeze+Send> ARC<T> {
|
||||
pub fn get<'a>(&'a self) -> &'a T {
|
||||
unsafe { &*self.x.get_immut() }
|
||||
}
|
||||
|
|
@ -133,7 +132,7 @@ impl<T:Const+Owned> ARC<T> {
|
|||
* object. However, one of the `arc` objects can be sent to another task,
|
||||
* allowing them to share the underlying data.
|
||||
*/
|
||||
impl<T:Const + Owned> Clone for ARC<T> {
|
||||
impl<T:Freeze + Send> Clone for ARC<T> {
|
||||
fn clone(&self) -> ARC<T> {
|
||||
ARC { x: self.x.clone() }
|
||||
}
|
||||
|
|
@ -149,14 +148,14 @@ struct MutexARCInner<T> { lock: Mutex, failed: bool, data: T }
|
|||
struct MutexARC<T> { x: UnsafeAtomicRcBox<MutexARCInner<T>> }
|
||||
|
||||
/// Create a mutex-protected ARC with the supplied data.
|
||||
pub fn MutexARC<T:Owned>(user_data: T) -> MutexARC<T> {
|
||||
pub fn MutexARC<T:Send>(user_data: T) -> MutexARC<T> {
|
||||
mutex_arc_with_condvars(user_data, 1)
|
||||
}
|
||||
/**
|
||||
* Create a mutex-protected ARC with the supplied data and a specified number
|
||||
* of condvars (as sync::mutex_with_condvars).
|
||||
*/
|
||||
pub fn mutex_arc_with_condvars<T:Owned>(user_data: T,
|
||||
pub fn mutex_arc_with_condvars<T:Send>(user_data: T,
|
||||
num_condvars: uint) -> MutexARC<T> {
|
||||
let data =
|
||||
MutexARCInner { lock: mutex_with_condvars(num_condvars),
|
||||
|
|
@ -164,7 +163,7 @@ pub fn mutex_arc_with_condvars<T:Owned>(user_data: T,
|
|||
MutexARC { x: UnsafeAtomicRcBox::new(data) }
|
||||
}
|
||||
|
||||
impl<T:Owned> Clone for MutexARC<T> {
|
||||
impl<T:Send> Clone for MutexARC<T> {
|
||||
/// Duplicate a mutex-protected ARC, as arc::clone.
|
||||
fn clone(&self) -> MutexARC<T> {
|
||||
// NB: Cloning the underlying mutex is not necessary. Its reference
|
||||
|
|
@ -173,7 +172,7 @@ impl<T:Owned> Clone for MutexARC<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Owned> MutexARC<T> {
|
||||
impl<T:Send> MutexARC<T> {
|
||||
|
||||
/**
|
||||
* Access the underlying mutable data with mutual exclusion from other
|
||||
|
|
@ -247,7 +246,7 @@ struct PoisonOnFail {
|
|||
}
|
||||
|
||||
impl Drop for PoisonOnFail {
|
||||
fn finalize(&self) {
|
||||
fn drop(&self) {
|
||||
unsafe {
|
||||
/* assert!(!*self.failed);
|
||||
-- might be false in case of cond.wait() */
|
||||
|
|
@ -276,20 +275,21 @@ struct RWARCInner<T> { lock: RWlock, failed: bool, data: T }
|
|||
*
|
||||
* Unlike mutex_arcs, rw_arcs are safe, because they cannot be nested.
|
||||
*/
|
||||
#[mutable]
|
||||
#[mutable] // XXX remove after snap
|
||||
#[no_freeze]
|
||||
struct RWARC<T> {
|
||||
x: UnsafeAtomicRcBox<RWARCInner<T>>,
|
||||
}
|
||||
|
||||
/// Create a reader/writer ARC with the supplied data.
|
||||
pub fn RWARC<T:Const + Owned>(user_data: T) -> RWARC<T> {
|
||||
pub fn RWARC<T:Freeze + Send>(user_data: T) -> RWARC<T> {
|
||||
rw_arc_with_condvars(user_data, 1)
|
||||
}
|
||||
/**
|
||||
* Create a reader/writer ARC with the supplied data and a specified number
|
||||
* of condvars (as sync::rwlock_with_condvars).
|
||||
*/
|
||||
pub fn rw_arc_with_condvars<T:Const + Owned>(
|
||||
pub fn rw_arc_with_condvars<T:Freeze + Send>(
|
||||
user_data: T,
|
||||
num_condvars: uint) -> RWARC<T>
|
||||
{
|
||||
|
|
@ -299,7 +299,7 @@ pub fn rw_arc_with_condvars<T:Const + Owned>(
|
|||
RWARC { x: UnsafeAtomicRcBox::new(data), }
|
||||
}
|
||||
|
||||
impl<T:Const + Owned> RWARC<T> {
|
||||
impl<T:Freeze + Send> RWARC<T> {
|
||||
/// Duplicate a rwlock-protected ARC, as arc::clone.
|
||||
pub fn clone(&self) -> RWARC<T> {
|
||||
RWARC {
|
||||
|
|
@ -309,7 +309,7 @@ impl<T:Const + Owned> RWARC<T> {
|
|||
|
||||
}
|
||||
|
||||
impl<T:Const + Owned> RWARC<T> {
|
||||
impl<T:Freeze + Send> RWARC<T> {
|
||||
/**
|
||||
* Access the underlying data mutably. Locks the rwlock in write mode;
|
||||
* other readers and writers will block.
|
||||
|
|
@ -435,8 +435,8 @@ impl<T:Const + Owned> RWARC<T> {
|
|||
// lock it. This wraps the unsafety, with the justification that the 'lock'
|
||||
// field is never overwritten; only 'failed' and 'data'.
|
||||
#[doc(hidden)]
|
||||
fn borrow_rwlock<T:Const + Owned>(state: *const RWARCInner<T>) -> *RWlock {
|
||||
unsafe { cast::transmute(&const (*state).lock) }
|
||||
fn borrow_rwlock<T:Freeze + Send>(state: *mut RWARCInner<T>) -> *RWlock {
|
||||
unsafe { cast::transmute(&(*state).lock) }
|
||||
}
|
||||
|
||||
/// The "write permission" token used for RWARC.write_downgrade().
|
||||
|
|
@ -452,7 +452,7 @@ pub struct RWReadMode<'self, T> {
|
|||
token: sync::RWlockReadMode<'self>,
|
||||
}
|
||||
|
||||
impl<'self, T:Const + Owned> RWWriteMode<'self, T> {
|
||||
impl<'self, T:Freeze + Send> RWWriteMode<'self, T> {
|
||||
/// Access the pre-downgrade RWARC in write mode.
|
||||
pub fn write<U>(&mut self, blk: &fn(x: &mut T) -> U) -> U {
|
||||
match *self {
|
||||
|
|
@ -493,7 +493,7 @@ impl<'self, T:Const + Owned> RWWriteMode<'self, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'self, T:Const + Owned> RWReadMode<'self, T> {
|
||||
impl<'self, T:Freeze + Send> RWReadMode<'self, T> {
|
||||
/// Access the post-downgrade rwlock in read mode.
|
||||
pub fn read<U>(&self, blk: &fn(x: &T) -> U) -> U {
|
||||
match *self {
|
||||
|
|
@ -513,13 +513,13 @@ impl<'self, T:Const + Owned> RWReadMode<'self, T> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use core::prelude::*;
|
||||
|
||||
use arc::*;
|
||||
|
||||
use core::cell::Cell;
|
||||
use core::comm;
|
||||
use core::task;
|
||||
use std::cell::Cell;
|
||||
use std::comm;
|
||||
use std::task;
|
||||
use std::uint;
|
||||
|
||||
#[test]
|
||||
fn manually_share_arc() {
|
||||
|
|
@ -725,7 +725,7 @@ mod tests {
|
|||
}
|
||||
|
||||
// Wait for children to pass their asserts
|
||||
for children.each |r| {
|
||||
for children.iter().advance |r| {
|
||||
r.recv();
|
||||
}
|
||||
|
||||
|
|
@ -789,18 +789,20 @@ mod tests {
|
|||
}
|
||||
assert_eq!(*state, 42);
|
||||
*state = 31337;
|
||||
// FIXME: #7372: hits type inference bug with iterators
|
||||
// send to other readers
|
||||
for reader_convos.each |x| {
|
||||
match *x {
|
||||
for uint::range(0, reader_convos.len()) |i| {
|
||||
match reader_convos[i] {
|
||||
(ref rc, _) => rc.send(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
let read_mode = arc.downgrade(write_mode);
|
||||
do (&read_mode).read |state| {
|
||||
// FIXME: #7372: hits type inference bug with iterators
|
||||
// complete handshake with other readers
|
||||
for reader_convos.each |x| {
|
||||
match *x {
|
||||
for uint::range(0, reader_convos.len()) |i| {
|
||||
match reader_convos[i] {
|
||||
(_, ref rp) => rp.recv(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -34,37 +34,27 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use list::{MutList, MutCons, MutNil};
|
||||
|
||||
use core::at_vec;
|
||||
use core::cast::{transmute, transmute_mut_region};
|
||||
use core::cast;
|
||||
use core::libc::size_t;
|
||||
use core::ptr;
|
||||
use core::sys::TypeDesc;
|
||||
use core::sys;
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use core::unstable::intrinsics;
|
||||
use std::at_vec;
|
||||
use std::cast::{transmute, transmute_mut, transmute_mut_region};
|
||||
use std::cast;
|
||||
use std::ptr;
|
||||
use std::sys;
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
use std::unstable::intrinsics;
|
||||
use std::unstable::intrinsics::{TyDesc};
|
||||
|
||||
pub mod rustrt {
|
||||
use core::libc::size_t;
|
||||
use core::sys::TypeDesc;
|
||||
#[cfg(not(stage0))]
|
||||
use std::unstable::intrinsics::{get_tydesc};
|
||||
|
||||
pub extern {
|
||||
#[rust_stack]
|
||||
unsafe fn rust_call_tydesc_glue(root: *u8,
|
||||
tydesc: *TypeDesc,
|
||||
field: size_t);
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
unsafe fn get_tydesc<T>() -> *TyDesc {
|
||||
intrinsics::get_tydesc::<T>() as *TyDesc
|
||||
}
|
||||
|
||||
// This probably belongs somewhere else. Needs to be kept in sync with
|
||||
// changes to glue...
|
||||
static tydesc_drop_glue_index: size_t = 3 as size_t;
|
||||
|
||||
// The way arena uses arrays is really deeply awful. The arrays are
|
||||
// allocated, and have capacities reserved, but the fill for the array
|
||||
// will always stay at 0.
|
||||
|
|
@ -74,6 +64,8 @@ struct Chunk {
|
|||
is_pod: bool,
|
||||
}
|
||||
|
||||
#[mutable] // XXX remove after snap
|
||||
#[no_freeze]
|
||||
pub struct Arena {
|
||||
// The head is separated out from the list as a unbenchmarked
|
||||
// microoptimization, to avoid needing to case on the list to
|
||||
|
|
@ -85,7 +77,7 @@ pub struct Arena {
|
|||
|
||||
#[unsafe_destructor]
|
||||
impl Drop for Arena {
|
||||
fn finalize(&self) {
|
||||
fn drop(&self) {
|
||||
unsafe {
|
||||
destroy_chunk(&self.head);
|
||||
for self.chunks.each |chunk| {
|
||||
|
|
@ -124,6 +116,19 @@ fn round_up_to(base: uint, align: uint) -> uint {
|
|||
(base + (align - 1)) & !(align - 1)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(not(stage0))]
|
||||
unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
|
||||
// This function should be inlined when stage0 is gone
|
||||
((*tydesc).drop_glue)(data);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(stage0)]
|
||||
unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
|
||||
((*tydesc).drop_glue)(0 as **TyDesc, data);
|
||||
}
|
||||
|
||||
// Walk down a chunk, running the destructors for any objects stored
|
||||
// in it.
|
||||
unsafe fn destroy_chunk(chunk: &Chunk) {
|
||||
|
|
@ -136,19 +141,18 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
|
|||
let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
|
||||
let (size, align) = ((*tydesc).size, (*tydesc).align);
|
||||
|
||||
let after_tydesc = idx + sys::size_of::<*TypeDesc>();
|
||||
let after_tydesc = idx + sys::size_of::<*TyDesc>();
|
||||
|
||||
let start = round_up_to(after_tydesc, align);
|
||||
|
||||
//debug!("freeing object: idx = %u, size = %u, align = %u, done = %b",
|
||||
// start, size, align, is_done);
|
||||
if is_done {
|
||||
rustrt::rust_call_tydesc_glue(
|
||||
ptr::offset(buf, start), tydesc, tydesc_drop_glue_index);
|
||||
call_drop_glue(tydesc, ptr::offset(buf, start) as *i8);
|
||||
}
|
||||
|
||||
// Find where the next tydesc lives
|
||||
idx = round_up_to(start + size, sys::pref_align_of::<*TypeDesc>());
|
||||
idx = round_up_to(start + size, sys::pref_align_of::<*TyDesc>());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -157,12 +161,12 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
|
|||
// is necessary in order to properly do cleanup if a failure occurs
|
||||
// during an initializer.
|
||||
#[inline]
|
||||
unsafe fn bitpack_tydesc_ptr(p: *TypeDesc, is_done: bool) -> uint {
|
||||
unsafe fn bitpack_tydesc_ptr(p: *TyDesc, is_done: bool) -> uint {
|
||||
let p_bits: uint = transmute(p);
|
||||
p_bits | (is_done as uint)
|
||||
}
|
||||
#[inline]
|
||||
unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TypeDesc, bool) {
|
||||
unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TyDesc, bool) {
|
||||
(transmute(p & !1), p & 1 == 1)
|
||||
}
|
||||
|
||||
|
|
@ -182,27 +186,25 @@ impl Arena {
|
|||
#[inline]
|
||||
fn alloc_pod_inner(&mut self, n_bytes: uint, align: uint) -> *u8 {
|
||||
unsafe {
|
||||
// XXX: Borrow check
|
||||
let head = transmute_mut_region(&mut self.pod_head);
|
||||
|
||||
let start = round_up_to(head.fill, align);
|
||||
let this = transmute_mut_region(self);
|
||||
let start = round_up_to(this.pod_head.fill, align);
|
||||
let end = start + n_bytes;
|
||||
if end > at_vec::capacity(head.data) {
|
||||
return self.alloc_pod_grow(n_bytes, align);
|
||||
if end > at_vec::capacity(this.pod_head.data) {
|
||||
return this.alloc_pod_grow(n_bytes, align);
|
||||
}
|
||||
head.fill = end;
|
||||
this.pod_head.fill = end;
|
||||
|
||||
//debug!("idx = %u, size = %u, align = %u, fill = %u",
|
||||
// start, n_bytes, align, head.fill);
|
||||
|
||||
ptr::offset(vec::raw::to_ptr(head.data), start)
|
||||
ptr::offset(vec::raw::to_ptr(this.pod_head.data), start)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn alloc_pod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T {
|
||||
unsafe {
|
||||
let tydesc = sys::get_type_desc::<T>();
|
||||
let tydesc = get_tydesc::<T>();
|
||||
let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
|
||||
let ptr: *mut T = transmute(ptr);
|
||||
intrinsics::move_val_init(&mut (*ptr), op());
|
||||
|
|
@ -227,21 +229,31 @@ impl Arena {
|
|||
fn alloc_nonpod_inner(&mut self, n_bytes: uint, align: uint)
|
||||
-> (*u8, *u8) {
|
||||
unsafe {
|
||||
let head = transmute_mut_region(&mut self.head);
|
||||
let start;
|
||||
let end;
|
||||
let tydesc_start;
|
||||
let after_tydesc;
|
||||
|
||||
let tydesc_start = head.fill;
|
||||
let after_tydesc = head.fill + sys::size_of::<*TypeDesc>();
|
||||
let start = round_up_to(after_tydesc, align);
|
||||
let end = start + n_bytes;
|
||||
if end > at_vec::capacity(head.data) {
|
||||
{
|
||||
let head = transmute_mut_region(&mut self.head);
|
||||
|
||||
tydesc_start = head.fill;
|
||||
after_tydesc = head.fill + sys::size_of::<*TyDesc>();
|
||||
start = round_up_to(after_tydesc, align);
|
||||
end = start + n_bytes;
|
||||
}
|
||||
|
||||
if end > at_vec::capacity(self.head.data) {
|
||||
return self.alloc_nonpod_grow(n_bytes, align);
|
||||
}
|
||||
head.fill = round_up_to(end, sys::pref_align_of::<*TypeDesc>());
|
||||
|
||||
let head = transmute_mut_region(&mut self.head);
|
||||
head.fill = round_up_to(end, sys::pref_align_of::<*TyDesc>());
|
||||
|
||||
//debug!("idx = %u, size = %u, align = %u, fill = %u",
|
||||
// start, n_bytes, align, head.fill);
|
||||
|
||||
let buf = vec::raw::to_ptr(head.data);
|
||||
let buf = vec::raw::to_ptr(self.head.data);
|
||||
return (ptr::offset(buf, tydesc_start), ptr::offset(buf, start));
|
||||
}
|
||||
}
|
||||
|
|
@ -249,7 +261,7 @@ impl Arena {
|
|||
#[inline]
|
||||
fn alloc_nonpod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T {
|
||||
unsafe {
|
||||
let tydesc = sys::get_type_desc::<T>();
|
||||
let tydesc = get_tydesc::<T>();
|
||||
let (ty_ptr, ptr) =
|
||||
self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align);
|
||||
let ty_ptr: *mut uint = transmute(ty_ptr);
|
||||
|
|
@ -269,23 +281,22 @@ impl Arena {
|
|||
|
||||
// The external interface
|
||||
#[inline]
|
||||
pub fn alloc<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T {
|
||||
pub fn alloc<'a, T>(&'a self, op: &fn() -> T) -> &'a T {
|
||||
unsafe {
|
||||
// XXX: Borrow check
|
||||
let this = transmute_mut_region(self);
|
||||
if !intrinsics::needs_drop::<T>() {
|
||||
return this.alloc_pod(op);
|
||||
let this = transmute_mut(self);
|
||||
if intrinsics::needs_drop::<T>() {
|
||||
this.alloc_nonpod(op)
|
||||
} else {
|
||||
this.alloc_pod(op)
|
||||
}
|
||||
// XXX: Borrow check
|
||||
let this = transmute_mut_region(self);
|
||||
this.alloc_nonpod(op)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_arena_destructors() {
|
||||
let mut arena = Arena();
|
||||
let arena = Arena();
|
||||
for uint::range(0, 10) |i| {
|
||||
// Arena allocate something with drop glue to make sure it
|
||||
// doesn't leak.
|
||||
|
|
@ -300,7 +311,7 @@ fn test_arena_destructors() {
|
|||
#[should_fail]
|
||||
#[ignore(cfg(windows))]
|
||||
fn test_arena_destructors_fail() {
|
||||
let mut arena = Arena();
|
||||
let arena = Arena();
|
||||
// Put some stuff in the arena.
|
||||
for uint::range(0, 10) |i| {
|
||||
// Arena allocate something with drop glue to make sure it
|
||||
|
|
|
|||
|
|
@ -10,9 +10,8 @@
|
|||
|
||||
//! Base64 binary-to-text encoding
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::vec;
|
||||
use std::vec;
|
||||
|
||||
/// A trait for converting a value to base64 encoding.
|
||||
pub trait ToBase64 {
|
||||
|
|
@ -36,8 +35,8 @@ impl<'self> ToBase64 for &'self [u8] {
|
|||
* # Example
|
||||
*
|
||||
* ~~~ {.rust}
|
||||
* extern mod std;
|
||||
* use std::base64::ToBase64;
|
||||
* extern mod extra;
|
||||
* use extra::base64::ToBase64;
|
||||
*
|
||||
* fn main () {
|
||||
* let str = [52,32].to_base64();
|
||||
|
|
@ -99,8 +98,8 @@ impl<'self> ToBase64 for &'self str {
|
|||
* # Example
|
||||
*
|
||||
* ~~~ {.rust}
|
||||
* extern mod std;
|
||||
* use std::base64::ToBase64;
|
||||
* extern mod extra;
|
||||
* use extra::base64::ToBase64;
|
||||
*
|
||||
* fn main () {
|
||||
* let str = "Hello, World".to_base64();
|
||||
|
|
@ -127,9 +126,9 @@ impl<'self> FromBase64 for &'self [u8] {
|
|||
* # Example
|
||||
*
|
||||
* ~~~ {.rust}
|
||||
* extern mod std;
|
||||
* use std::base64::ToBase64;
|
||||
* use std::base64::FromBase64;
|
||||
* extern mod extra;
|
||||
* use extra::base64::ToBase64;
|
||||
* use extra::base64::FromBase64;
|
||||
*
|
||||
* fn main () {
|
||||
* let str = [52,32].to_base64();
|
||||
|
|
@ -199,7 +198,7 @@ impl<'self> FromBase64 for &'self str {
|
|||
* Convert any base64 encoded string (literal, `@`, `&`, or `~`)
|
||||
* to the byte values it encodes.
|
||||
*
|
||||
* You can use the `from_bytes` function in `core::str`
|
||||
* You can use the `from_bytes` function in `std::str`
|
||||
* to turn a `[u8]` into a string with characters corresponding to those values.
|
||||
*
|
||||
* # Example
|
||||
|
|
@ -207,10 +206,10 @@ impl<'self> FromBase64 for &'self str {
|
|||
* This converts a string literal to base64 and back.
|
||||
*
|
||||
* ~~~ {.rust}
|
||||
* extern mod std;
|
||||
* use std::base64::ToBase64;
|
||||
* use std::base64::FromBase64;
|
||||
* use core::str;
|
||||
* extern mod extra;
|
||||
* use extra::base64::ToBase64;
|
||||
* use extra::base64::FromBase64;
|
||||
* use std::str;
|
||||
*
|
||||
* fn main () {
|
||||
* let hello_str = "Hello, World".to_base64();
|
||||
|
|
|
|||
|
|
@ -10,12 +10,11 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::cmp;
|
||||
use core::ops;
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use std::cmp;
|
||||
use std::ops;
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
|
||||
struct SmallBitv {
|
||||
/// only the lowest nbits of this value are used. the rest is undefined.
|
||||
|
|
@ -476,9 +475,15 @@ impl Bitv {
|
|||
* character is either '0' or '1'.
|
||||
*/
|
||||
pub fn to_str(&self) -> ~str {
|
||||
let mut rs = ~"";
|
||||
for self.each() |i| { if i { rs += "1"; } else { rs += "0"; } };
|
||||
rs
|
||||
let mut rs = ~"";
|
||||
for self.each() |i| {
|
||||
if i {
|
||||
rs.push_char('1');
|
||||
} else {
|
||||
rs.push_char('0');
|
||||
}
|
||||
};
|
||||
rs
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -639,7 +644,7 @@ impl BitvSet {
|
|||
if self.capacity() < other.capacity() {
|
||||
self.bitv.storage.grow(other.capacity() / uint::bits, &0);
|
||||
}
|
||||
for other.bitv.storage.eachi |i, &w| {
|
||||
for other.bitv.storage.iter().enumerate().advance |(i, &w)| {
|
||||
let old = self.bitv.storage[i];
|
||||
let new = f(old, w);
|
||||
self.bitv.storage[i] = new;
|
||||
|
|
@ -666,13 +671,9 @@ impl BitvSet {
|
|||
pub fn symmetric_difference_with(&mut self, other: &BitvSet) {
|
||||
self.other_op(other, |w1, w2| w1 ^ w2);
|
||||
}
|
||||
}
|
||||
|
||||
impl BaseIter<uint> for BitvSet {
|
||||
fn size_hint(&self) -> Option<uint> { Some(self.len()) }
|
||||
|
||||
fn each(&self, blk: &fn(v: &uint) -> bool) -> bool {
|
||||
for self.bitv.storage.eachi |i, &w| {
|
||||
pub fn each(&self, blk: &fn(v: &uint) -> bool) -> bool {
|
||||
for self.bitv.storage.iter().enumerate().advance |(i, &w)| {
|
||||
if !iterate_bits(i * uint::bits, w, |b| blk(&b)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -703,8 +704,8 @@ impl cmp::Eq for BitvSet {
|
|||
}
|
||||
|
||||
impl Container for BitvSet {
|
||||
fn len(&const self) -> uint { self.size }
|
||||
fn is_empty(&const self) -> bool { self.size == 0 }
|
||||
fn len(&self) -> uint { self.size }
|
||||
fn is_empty(&self) -> bool { self.size == 0 }
|
||||
}
|
||||
|
||||
impl Mutable for BitvSet {
|
||||
|
|
@ -826,7 +827,7 @@ impl BitvSet {
|
|||
f: &fn(uint, uint, uint) -> bool) -> bool {
|
||||
let min = uint::min(self.bitv.storage.len(),
|
||||
other.bitv.storage.len());
|
||||
self.bitv.storage.slice(0, min).eachi(|i, &w| {
|
||||
self.bitv.storage.slice(0, min).iter().enumerate().advance(|(i, &w)| {
|
||||
f(i * uint::bits, w, other.bitv.storage[i])
|
||||
})
|
||||
}
|
||||
|
|
@ -845,12 +846,12 @@ impl BitvSet {
|
|||
let min = uint::min(len1, len2);
|
||||
|
||||
/* only one of these loops will execute and that's the point */
|
||||
for self.bitv.storage.slice(min, len1).eachi |i, &w| {
|
||||
for self.bitv.storage.slice(min, len1).iter().enumerate().advance |(i, &w)| {
|
||||
if !f(true, (i + min) * uint::bits, w) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for other.bitv.storage.slice(min, len2).eachi |i, &w| {
|
||||
for other.bitv.storage.slice(min, len2).iter().enumerate().advance |(i, &w)| {
|
||||
if !f(false, (i + min) * uint::bits, w) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -861,15 +862,15 @@ impl BitvSet {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::test::BenchHarness;
|
||||
use extra::test::BenchHarness;
|
||||
|
||||
use bitv::*;
|
||||
use bitv;
|
||||
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use core::rand;
|
||||
use core::rand::Rng;
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
use std::rand;
|
||||
use std::rand::Rng;
|
||||
|
||||
static bench_bits : uint = 1 << 14;
|
||||
|
||||
|
|
|
|||
|
|
@ -36,10 +36,9 @@
|
|||
* still held if needed.
|
||||
*/
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::option;
|
||||
use core::ptr;
|
||||
use std::option;
|
||||
use std::ptr;
|
||||
|
||||
/**
|
||||
* The type representing a foreign chunk of memory
|
||||
|
|
@ -57,7 +56,7 @@ struct DtorRes {
|
|||
|
||||
#[unsafe_destructor]
|
||||
impl Drop for DtorRes {
|
||||
fn finalize(&self) {
|
||||
fn drop(&self) {
|
||||
match self.dtor {
|
||||
option::None => (),
|
||||
option::Some(f) => f()
|
||||
|
|
@ -150,8 +149,8 @@ mod tests {
|
|||
|
||||
use c_vec::*;
|
||||
|
||||
use core::libc::*;
|
||||
use core::libc;
|
||||
use std::libc::*;
|
||||
use std::libc;
|
||||
|
||||
fn malloc(n: size_t) -> CVec<u8> {
|
||||
unsafe {
|
||||
|
|
@ -159,8 +158,7 @@ mod tests {
|
|||
|
||||
assert!(mem as int != 0);
|
||||
|
||||
return c_vec_with_dtor(mem as *mut u8, n as uint,
|
||||
|| unsafe { free(mem) });
|
||||
c_vec_with_dtor(mem as *mut u8, n as uint, || free(mem))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,12 +16,11 @@ Higher level communication abstractions.
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::comm::{GenericChan, GenericSmartChan, GenericPort};
|
||||
use core::comm::{Chan, Port, Selectable, Peekable};
|
||||
use core::comm;
|
||||
use core::pipes;
|
||||
use std::comm::{GenericChan, GenericSmartChan, GenericPort};
|
||||
use std::comm::{Chan, Port, Selectable, Peekable};
|
||||
use std::comm;
|
||||
use std::pipes;
|
||||
|
||||
/// An extension of `pipes::stream` that allows both sending and receiving.
|
||||
pub struct DuplexStream<T, U> {
|
||||
|
|
@ -30,7 +29,7 @@ pub struct DuplexStream<T, U> {
|
|||
}
|
||||
|
||||
// Allow these methods to be used without import:
|
||||
impl<T:Owned,U:Owned> DuplexStream<T, U> {
|
||||
impl<T:Send,U:Send> DuplexStream<T, U> {
|
||||
pub fn send(&self, x: T) {
|
||||
self.chan.send(x)
|
||||
}
|
||||
|
|
@ -48,19 +47,19 @@ impl<T:Owned,U:Owned> DuplexStream<T, U> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Owned,U:Owned> GenericChan<T> for DuplexStream<T, U> {
|
||||
impl<T:Send,U:Send> GenericChan<T> for DuplexStream<T, U> {
|
||||
fn send(&self, x: T) {
|
||||
self.chan.send(x)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Owned,U:Owned> GenericSmartChan<T> for DuplexStream<T, U> {
|
||||
impl<T:Send,U:Send> GenericSmartChan<T> for DuplexStream<T, U> {
|
||||
fn try_send(&self, x: T) -> bool {
|
||||
self.chan.try_send(x)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Owned,U:Owned> GenericPort<U> for DuplexStream<T, U> {
|
||||
impl<T:Send,U:Send> GenericPort<U> for DuplexStream<T, U> {
|
||||
fn recv(&self) -> U {
|
||||
self.port.recv()
|
||||
}
|
||||
|
|
@ -70,20 +69,20 @@ impl<T:Owned,U:Owned> GenericPort<U> for DuplexStream<T, U> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Owned,U:Owned> Peekable<U> for DuplexStream<T, U> {
|
||||
impl<T:Send,U:Send> Peekable<U> for DuplexStream<T, U> {
|
||||
fn peek(&self) -> bool {
|
||||
self.port.peek()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Owned,U:Owned> Selectable for DuplexStream<T, U> {
|
||||
impl<T:Send,U:Send> Selectable for DuplexStream<T, U> {
|
||||
fn header(&mut self) -> *mut pipes::PacketHeader {
|
||||
self.port.header()
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a bidirectional stream.
|
||||
pub fn DuplexStream<T:Owned,U:Owned>()
|
||||
pub fn DuplexStream<T:Send,U:Send>()
|
||||
-> (DuplexStream<T, U>, DuplexStream<U, T>)
|
||||
{
|
||||
let (p1, c2) = comm::stream();
|
||||
|
|
|
|||
87
src/libextra/crypto/digest.rs
Normal file
87
src/libextra/crypto/digest.rs
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
|
||||
/**
|
||||
* The Digest trait specifies an interface common to digest functions, such as SHA-1 and the SHA-2
|
||||
* family of digest functions.
|
||||
*/
|
||||
pub trait Digest {
|
||||
/**
|
||||
* Provide message data.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * input - A vector of message data
|
||||
*/
|
||||
fn input(&mut self, input: &[u8]);
|
||||
|
||||
/**
|
||||
* Retrieve the digest result. This method may be called multiple times.
|
||||
*/
|
||||
fn result(&mut self, out: &mut [u8]);
|
||||
|
||||
/**
|
||||
* Reset the digest. This method must be called after result() and before supplying more
|
||||
* data.
|
||||
*/
|
||||
fn reset(&mut self);
|
||||
|
||||
/**
|
||||
* Get the output size in bits.
|
||||
*/
|
||||
fn output_bits(&self) -> uint;
|
||||
}
|
||||
|
||||
fn to_hex(rr: &[u8]) -> ~str {
|
||||
let mut s = ~"";
|
||||
for rr.iter().advance() |b| {
|
||||
let hex = uint::to_str_radix(*b as uint, 16u);
|
||||
if hex.len() == 1 {
|
||||
s.push_char('0');
|
||||
}
|
||||
s.push_str(hex);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Contains utility methods for Digests.
|
||||
/// FIXME: #7339: Convert to default methods when issues with them are resolved.
|
||||
pub trait DigestUtil {
|
||||
/**
|
||||
* Convenience functon that feeds a string into a digest
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * in The string to feed into the digest
|
||||
*/
|
||||
fn input_str(&mut self, in: &str);
|
||||
|
||||
/**
|
||||
* Convenience functon that retrieves the result of a digest as a
|
||||
* ~str in hexadecimal format.
|
||||
*/
|
||||
fn result_str(&mut self) -> ~str;
|
||||
}
|
||||
|
||||
impl<D: Digest> DigestUtil for D {
|
||||
fn input_str(&mut self, in: &str) {
|
||||
self.input(in.as_bytes());
|
||||
}
|
||||
|
||||
fn result_str(&mut self) -> ~str {
|
||||
let mut buf = vec::from_elem((self.output_bits()+7)/8, 0u8);
|
||||
self.result(buf);
|
||||
return to_hex(buf);
|
||||
}
|
||||
}
|
||||
369
src/libextra/crypto/sha1.rs
Normal file
369
src/libextra/crypto/sha1.rs
Normal file
|
|
@ -0,0 +1,369 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/*!
|
||||
* An implementation of the SHA-1 cryptographic hash.
|
||||
*
|
||||
* First create a `sha1` object using the `sha1` constructor, then
|
||||
* feed it input using the `input` or `input_str` methods, which may be
|
||||
* called any number of times.
|
||||
*
|
||||
* After the entire input has been fed to the hash read the result using
|
||||
* the `result` or `result_str` methods.
|
||||
*
|
||||
* The `sha1` object may be reused to create multiple hashes by calling
|
||||
* the `reset` method.
|
||||
*/
|
||||
|
||||
|
||||
use digest::Digest;
|
||||
|
||||
/*
|
||||
* A SHA-1 implementation derived from Paul E. Jones's reference
|
||||
* implementation, which is written for clarity, not speed. At some
|
||||
* point this will want to be rewritten.
|
||||
*/
|
||||
|
||||
// Some unexported constants
|
||||
static DIGEST_BUF_LEN: uint = 5u;
|
||||
static MSG_BLOCK_LEN: uint = 64u;
|
||||
static WORK_BUF_LEN: uint = 80u;
|
||||
static K0: u32 = 0x5A827999u32;
|
||||
static K1: u32 = 0x6ED9EBA1u32;
|
||||
static K2: u32 = 0x8F1BBCDCu32;
|
||||
static K3: u32 = 0xCA62C1D6u32;
|
||||
|
||||
/// Structure representing the state of a Sha1 computation
|
||||
pub struct Sha1 {
|
||||
priv h: [u32, ..DIGEST_BUF_LEN],
|
||||
priv len_low: u32,
|
||||
priv len_high: u32,
|
||||
priv msg_block: [u8, ..MSG_BLOCK_LEN],
|
||||
priv msg_block_idx: uint,
|
||||
priv computed: bool,
|
||||
priv work_buf: [u32, ..WORK_BUF_LEN]
|
||||
}
|
||||
|
||||
fn add_input(st: &mut Sha1, msg: &[u8]) {
|
||||
assert!((!st.computed));
|
||||
for msg.iter().advance |element| {
|
||||
st.msg_block[st.msg_block_idx] = *element;
|
||||
st.msg_block_idx += 1;
|
||||
st.len_low += 8;
|
||||
if st.len_low == 0 {
|
||||
st.len_high += 1;
|
||||
if st.len_high == 0 {
|
||||
// FIXME: Need better failure mode (#2346)
|
||||
fail!();
|
||||
}
|
||||
}
|
||||
if st.msg_block_idx == MSG_BLOCK_LEN { process_msg_block(st); }
|
||||
}
|
||||
}
|
||||
|
||||
fn process_msg_block(st: &mut Sha1) {
|
||||
let mut t: int; // Loop counter
|
||||
let mut w = st.work_buf;
|
||||
|
||||
// Initialize the first 16 words of the vector w
|
||||
t = 0;
|
||||
while t < 16 {
|
||||
let mut tmp;
|
||||
tmp = (st.msg_block[t * 4] as u32) << 24u32;
|
||||
tmp = tmp | (st.msg_block[t * 4 + 1] as u32) << 16u32;
|
||||
tmp = tmp | (st.msg_block[t * 4 + 2] as u32) << 8u32;
|
||||
tmp = tmp | (st.msg_block[t * 4 + 3] as u32);
|
||||
w[t] = tmp;
|
||||
t += 1;
|
||||
}
|
||||
|
||||
// Initialize the rest of vector w
|
||||
while t < 80 {
|
||||
let val = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16];
|
||||
w[t] = circular_shift(1, val);
|
||||
t += 1;
|
||||
}
|
||||
let mut a = st.h[0];
|
||||
let mut b = st.h[1];
|
||||
let mut c = st.h[2];
|
||||
let mut d = st.h[3];
|
||||
let mut e = st.h[4];
|
||||
let mut temp: u32;
|
||||
t = 0;
|
||||
while t < 20 {
|
||||
temp = circular_shift(5, a) + (b & c | !b & d) + e + w[t] + K0;
|
||||
e = d;
|
||||
d = c;
|
||||
c = circular_shift(30, b);
|
||||
b = a;
|
||||
a = temp;
|
||||
t += 1;
|
||||
}
|
||||
while t < 40 {
|
||||
temp = circular_shift(5, a) + (b ^ c ^ d) + e + w[t] + K1;
|
||||
e = d;
|
||||
d = c;
|
||||
c = circular_shift(30, b);
|
||||
b = a;
|
||||
a = temp;
|
||||
t += 1;
|
||||
}
|
||||
while t < 60 {
|
||||
temp =
|
||||
circular_shift(5, a) + (b & c | b & d | c & d) + e + w[t] +
|
||||
K2;
|
||||
e = d;
|
||||
d = c;
|
||||
c = circular_shift(30, b);
|
||||
b = a;
|
||||
a = temp;
|
||||
t += 1;
|
||||
}
|
||||
while t < 80 {
|
||||
temp = circular_shift(5, a) + (b ^ c ^ d) + e + w[t] + K3;
|
||||
e = d;
|
||||
d = c;
|
||||
c = circular_shift(30, b);
|
||||
b = a;
|
||||
a = temp;
|
||||
t += 1;
|
||||
}
|
||||
st.h[0] = st.h[0] + a;
|
||||
st.h[1] = st.h[1] + b;
|
||||
st.h[2] = st.h[2] + c;
|
||||
st.h[3] = st.h[3] + d;
|
||||
st.h[4] = st.h[4] + e;
|
||||
st.msg_block_idx = 0;
|
||||
}
|
||||
|
||||
fn circular_shift(bits: u32, word: u32) -> u32 {
|
||||
return word << bits | word >> 32u32 - bits;
|
||||
}
|
||||
|
||||
fn mk_result(st: &mut Sha1, rs: &mut [u8]) {
|
||||
if !st.computed { pad_msg(st); st.computed = true; }
|
||||
let mut i = 0;
|
||||
for st.h.mut_iter().advance |ptr_hpart| {
|
||||
let hpart = *ptr_hpart;
|
||||
rs[i] = (hpart >> 24u32 & 0xFFu32) as u8;
|
||||
rs[i+1] = (hpart >> 16u32 & 0xFFu32) as u8;
|
||||
rs[i+2] = (hpart >> 8u32 & 0xFFu32) as u8;
|
||||
rs[i+3] = (hpart & 0xFFu32) as u8;
|
||||
i += 4;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* According to the standard, the message must be padded to an even
|
||||
* 512 bits. The first padding bit must be a '1'. The last 64 bits
|
||||
* represent the length of the original message. All bits in between
|
||||
* should be 0. This function will pad the message according to those
|
||||
* rules by filling the msg_block vector accordingly. It will also
|
||||
* call process_msg_block() appropriately. When it returns, it
|
||||
* can be assumed that the message digest has been computed.
|
||||
*/
|
||||
fn pad_msg(st: &mut Sha1) {
|
||||
/*
|
||||
* Check to see if the current message block is too small to hold
|
||||
* the initial padding bits and length. If so, we will pad the
|
||||
* block, process it, and then continue padding into a second block.
|
||||
*/
|
||||
if st.msg_block_idx > 55 {
|
||||
st.msg_block[st.msg_block_idx] = 0x80;
|
||||
st.msg_block_idx += 1;
|
||||
while st.msg_block_idx < MSG_BLOCK_LEN {
|
||||
st.msg_block[st.msg_block_idx] = 0;
|
||||
st.msg_block_idx += 1;
|
||||
}
|
||||
process_msg_block(st);
|
||||
} else {
|
||||
st.msg_block[st.msg_block_idx] = 0x80;
|
||||
st.msg_block_idx += 1;
|
||||
}
|
||||
while st.msg_block_idx < 56 {
|
||||
st.msg_block[st.msg_block_idx] = 0u8;
|
||||
st.msg_block_idx += 1;
|
||||
}
|
||||
|
||||
// Store the message length as the last 8 octets
|
||||
st.msg_block[56] = (st.len_high >> 24u32 & 0xFFu32) as u8;
|
||||
st.msg_block[57] = (st.len_high >> 16u32 & 0xFFu32) as u8;
|
||||
st.msg_block[58] = (st.len_high >> 8u32 & 0xFFu32) as u8;
|
||||
st.msg_block[59] = (st.len_high & 0xFFu32) as u8;
|
||||
st.msg_block[60] = (st.len_low >> 24u32 & 0xFFu32) as u8;
|
||||
st.msg_block[61] = (st.len_low >> 16u32 & 0xFFu32) as u8;
|
||||
st.msg_block[62] = (st.len_low >> 8u32 & 0xFFu32) as u8;
|
||||
st.msg_block[63] = (st.len_low & 0xFFu32) as u8;
|
||||
process_msg_block(st);
|
||||
}
|
||||
|
||||
impl Sha1 {
|
||||
/// Construct a `sha` object
|
||||
pub fn new() -> Sha1 {
|
||||
let mut st = Sha1 {
|
||||
h: [0u32, ..DIGEST_BUF_LEN],
|
||||
len_low: 0u32,
|
||||
len_high: 0u32,
|
||||
msg_block: [0u8, ..MSG_BLOCK_LEN],
|
||||
msg_block_idx: 0,
|
||||
computed: false,
|
||||
work_buf: [0u32, ..WORK_BUF_LEN]
|
||||
};
|
||||
st.reset();
|
||||
return st;
|
||||
}
|
||||
}
|
||||
|
||||
impl Digest for Sha1 {
|
||||
pub fn reset(&mut self) {
|
||||
self.len_low = 0;
|
||||
self.len_high = 0;
|
||||
self.msg_block_idx = 0;
|
||||
self.h[0] = 0x67452301u32;
|
||||
self.h[1] = 0xEFCDAB89u32;
|
||||
self.h[2] = 0x98BADCFEu32;
|
||||
self.h[3] = 0x10325476u32;
|
||||
self.h[4] = 0xC3D2E1F0u32;
|
||||
self.computed = false;
|
||||
}
|
||||
pub fn input(&mut self, msg: &[u8]) { add_input(self, msg); }
|
||||
pub fn result(&mut self, out: &mut [u8]) { return mk_result(self, out); }
|
||||
pub fn output_bits(&self) -> uint { 160 }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::vec;
|
||||
|
||||
use digest::{Digest, DigestUtil};
|
||||
use sha1::Sha1;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
struct Test {
|
||||
input: ~str,
|
||||
output: ~[u8],
|
||||
output_str: ~str,
|
||||
}
|
||||
|
||||
fn a_million_letter_a() -> ~str {
|
||||
let mut i = 0;
|
||||
let mut rs = ~"";
|
||||
while i < 100000 {
|
||||
rs.push_str("aaaaaaaaaa");
|
||||
i += 1;
|
||||
}
|
||||
return rs;
|
||||
}
|
||||
// Test messages from FIPS 180-1
|
||||
|
||||
let fips_180_1_tests = ~[
|
||||
Test {
|
||||
input: ~"abc",
|
||||
output: ~[
|
||||
0xA9u8, 0x99u8, 0x3Eu8, 0x36u8,
|
||||
0x47u8, 0x06u8, 0x81u8, 0x6Au8,
|
||||
0xBAu8, 0x3Eu8, 0x25u8, 0x71u8,
|
||||
0x78u8, 0x50u8, 0xC2u8, 0x6Cu8,
|
||||
0x9Cu8, 0xD0u8, 0xD8u8, 0x9Du8,
|
||||
],
|
||||
output_str: ~"a9993e364706816aba3e25717850c26c9cd0d89d"
|
||||
},
|
||||
Test {
|
||||
input:
|
||||
~"abcdbcdecdefdefgefghfghighij" +
|
||||
"hijkijkljklmklmnlmnomnopnopq",
|
||||
output: ~[
|
||||
0x84u8, 0x98u8, 0x3Eu8, 0x44u8,
|
||||
0x1Cu8, 0x3Bu8, 0xD2u8, 0x6Eu8,
|
||||
0xBAu8, 0xAEu8, 0x4Au8, 0xA1u8,
|
||||
0xF9u8, 0x51u8, 0x29u8, 0xE5u8,
|
||||
0xE5u8, 0x46u8, 0x70u8, 0xF1u8,
|
||||
],
|
||||
output_str: ~"84983e441c3bd26ebaae4aa1f95129e5e54670f1"
|
||||
},
|
||||
Test {
|
||||
input: a_million_letter_a(),
|
||||
output: ~[
|
||||
0x34u8, 0xAAu8, 0x97u8, 0x3Cu8,
|
||||
0xD4u8, 0xC4u8, 0xDAu8, 0xA4u8,
|
||||
0xF6u8, 0x1Eu8, 0xEBu8, 0x2Bu8,
|
||||
0xDBu8, 0xADu8, 0x27u8, 0x31u8,
|
||||
0x65u8, 0x34u8, 0x01u8, 0x6Fu8,
|
||||
],
|
||||
output_str: ~"34aa973cd4c4daa4f61eeb2bdbad27316534016f"
|
||||
},
|
||||
];
|
||||
// Examples from wikipedia
|
||||
|
||||
let wikipedia_tests = ~[
|
||||
Test {
|
||||
input: ~"The quick brown fox jumps over the lazy dog",
|
||||
output: ~[
|
||||
0x2fu8, 0xd4u8, 0xe1u8, 0xc6u8,
|
||||
0x7au8, 0x2du8, 0x28u8, 0xfcu8,
|
||||
0xedu8, 0x84u8, 0x9eu8, 0xe1u8,
|
||||
0xbbu8, 0x76u8, 0xe7u8, 0x39u8,
|
||||
0x1bu8, 0x93u8, 0xebu8, 0x12u8,
|
||||
],
|
||||
output_str: ~"2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
|
||||
},
|
||||
Test {
|
||||
input: ~"The quick brown fox jumps over the lazy cog",
|
||||
output: ~[
|
||||
0xdeu8, 0x9fu8, 0x2cu8, 0x7fu8,
|
||||
0xd2u8, 0x5eu8, 0x1bu8, 0x3au8,
|
||||
0xfau8, 0xd3u8, 0xe8u8, 0x5au8,
|
||||
0x0bu8, 0xd1u8, 0x7du8, 0x9bu8,
|
||||
0x10u8, 0x0du8, 0xb4u8, 0xb3u8,
|
||||
],
|
||||
output_str: ~"de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3",
|
||||
},
|
||||
];
|
||||
let tests = fips_180_1_tests + wikipedia_tests;
|
||||
|
||||
// Test that it works when accepting the message all at once
|
||||
|
||||
let mut out = [0u8, ..20];
|
||||
|
||||
let mut sh = ~Sha1::new();
|
||||
for tests.iter().advance |t| {
|
||||
(*sh).input_str(t.input);
|
||||
sh.result(out);
|
||||
assert!(vec::eq(t.output, out));
|
||||
|
||||
let out_str = (*sh).result_str();
|
||||
assert_eq!(out_str.len(), 40);
|
||||
assert!(out_str == t.output_str);
|
||||
|
||||
sh.reset();
|
||||
}
|
||||
|
||||
|
||||
// Test that it works when accepting the message in pieces
|
||||
for tests.iter().advance |t| {
|
||||
let len = t.input.len();
|
||||
let mut left = len;
|
||||
while left > 0u {
|
||||
let take = (left + 1u) / 2u;
|
||||
(*sh).input_str(t.input.slice(len - left, take + len - left));
|
||||
left = left - take;
|
||||
}
|
||||
sh.result(out);
|
||||
assert!(vec::eq(t.output, out));
|
||||
|
||||
let out_str = (*sh).result_str();
|
||||
assert_eq!(out_str.len(), 40);
|
||||
assert!(out_str == t.output_str);
|
||||
|
||||
sh.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
1123
src/libextra/crypto/sha2.rs
Normal file
1123
src/libextra/crypto/sha2.rs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -12,57 +12,63 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::cast::transmute;
|
||||
use core::sys;
|
||||
use std::cast::transmute;
|
||||
#[cfg(stage0)]
|
||||
use intrinsic::{get_tydesc};
|
||||
#[cfg(not(stage0))]
|
||||
use std::unstable::intrinsics::{get_tydesc};
|
||||
|
||||
pub mod rustrt {
|
||||
use core::sys;
|
||||
#[cfg(stage0)]
|
||||
use intrinsic::{TyDesc};
|
||||
#[cfg(not(stage0))]
|
||||
use std::unstable::intrinsics::{TyDesc};
|
||||
|
||||
#[abi = "cdecl"]
|
||||
pub extern {
|
||||
pub unsafe fn debug_tydesc(td: *sys::TypeDesc);
|
||||
pub unsafe fn debug_opaque(td: *sys::TypeDesc, x: *());
|
||||
pub unsafe fn debug_box(td: *sys::TypeDesc, x: *());
|
||||
pub unsafe fn debug_tag(td: *sys::TypeDesc, x: *());
|
||||
pub unsafe fn debug_fn(td: *sys::TypeDesc, x: *());
|
||||
pub unsafe fn debug_ptrcast(td: *sys::TypeDesc, x: *()) -> *();
|
||||
pub unsafe fn debug_tydesc(td: *TyDesc);
|
||||
pub unsafe fn debug_opaque(td: *TyDesc, x: *());
|
||||
pub unsafe fn debug_box(td: *TyDesc, x: *());
|
||||
pub unsafe fn debug_tag(td: *TyDesc, x: *());
|
||||
pub unsafe fn debug_fn(td: *TyDesc, x: *());
|
||||
pub unsafe fn debug_ptrcast(td: *TyDesc, x: *()) -> *();
|
||||
pub unsafe fn rust_dbg_breakpoint();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn debug_tydesc<T>() {
|
||||
unsafe {
|
||||
rustrt::debug_tydesc(sys::get_type_desc::<T>());
|
||||
rustrt::debug_tydesc(get_tydesc::<T>());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn debug_opaque<T>(x: T) {
|
||||
unsafe {
|
||||
rustrt::debug_opaque(sys::get_type_desc::<T>(), transmute(&x));
|
||||
rustrt::debug_opaque(get_tydesc::<T>(), transmute(&x));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn debug_box<T>(x: @T) {
|
||||
unsafe {
|
||||
rustrt::debug_box(sys::get_type_desc::<T>(), transmute(&x));
|
||||
rustrt::debug_box(get_tydesc::<T>(), transmute(&x));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn debug_tag<T>(x: T) {
|
||||
unsafe {
|
||||
rustrt::debug_tag(sys::get_type_desc::<T>(), transmute(&x));
|
||||
rustrt::debug_tag(get_tydesc::<T>(), transmute(&x));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn debug_fn<T>(x: T) {
|
||||
unsafe {
|
||||
rustrt::debug_fn(sys::get_type_desc::<T>(), transmute(&x));
|
||||
rustrt::debug_fn(get_tydesc::<T>(), transmute(&x));
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn ptr_cast<T, U>(x: @T) -> @U {
|
||||
transmute(
|
||||
rustrt::debug_ptrcast(sys::get_type_desc::<T>(), transmute(x)))
|
||||
rustrt::debug_ptrcast(get_tydesc::<T>(), transmute(x)))
|
||||
}
|
||||
|
||||
/// Triggers a debugger breakpoint
|
||||
|
|
|
|||
|
|
@ -10,11 +10,10 @@
|
|||
|
||||
//! A double-ended queue implemented as a circular buffer
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::uint;
|
||||
use core::util::replace;
|
||||
use core::vec;
|
||||
use std::uint;
|
||||
use std::util::replace;
|
||||
use std::vec;
|
||||
use std::cast::transmute;
|
||||
|
||||
static initial_capacity: uint = 32u; // 2^5
|
||||
|
||||
|
|
@ -28,10 +27,10 @@ pub struct Deque<T> {
|
|||
|
||||
impl<T> Container for Deque<T> {
|
||||
/// Return the number of elements in the deque
|
||||
fn len(&const self) -> uint { self.nelts }
|
||||
fn len(&self) -> uint { self.nelts }
|
||||
|
||||
/// Return true if the deque contains no elements
|
||||
fn is_empty(&const self) -> bool { self.len() == 0 }
|
||||
fn is_empty(&self) -> bool { self.len() == 0 }
|
||||
}
|
||||
|
||||
impl<T> Mutable for Deque<T> {
|
||||
|
|
@ -137,7 +136,7 @@ impl<T> Deque<T> {
|
|||
///
|
||||
/// * n - The number of elements to reserve space for
|
||||
pub fn reserve(&mut self, n: uint) {
|
||||
vec::reserve(&mut self.elts, n);
|
||||
self.elts.reserve(n);
|
||||
}
|
||||
|
||||
/// Reserve capacity for at least `n` elements in the given deque,
|
||||
|
|
@ -151,10 +150,89 @@ impl<T> Deque<T> {
|
|||
///
|
||||
/// * n - The number of elements to reserve space for
|
||||
pub fn reserve_at_least(&mut self, n: uint) {
|
||||
vec::reserve_at_least(&mut self.elts, n);
|
||||
self.elts.reserve_at_least(n);
|
||||
}
|
||||
|
||||
/// Front-to-back iterator.
|
||||
pub fn iter<'a>(&'a self) -> DequeIterator<'a, T> {
|
||||
DequeIterator { idx: self.lo, nelts: self.nelts, used: 0, vec: self.elts }
|
||||
}
|
||||
|
||||
/// Front-to-back iterator which returns mutable values.
|
||||
pub fn mut_iter<'a>(&'a mut self) -> DequeMutIterator<'a, T> {
|
||||
DequeMutIterator { idx: self.lo, nelts: self.nelts, used: 0, vec: self.elts }
|
||||
}
|
||||
|
||||
/// Back-to-front iterator.
|
||||
pub fn rev_iter<'a>(&'a self) -> DequeRevIterator<'a, T> {
|
||||
DequeRevIterator { idx: self.hi - 1u, nelts: self.nelts, used: 0, vec: self.elts }
|
||||
}
|
||||
|
||||
/// Back-to-front iterator which returns mutable values.
|
||||
pub fn mut_rev_iter<'a>(&'a mut self) -> DequeMutRevIterator<'a, T> {
|
||||
DequeMutRevIterator { idx: self.hi - 1u, nelts: self.nelts, used: 0, vec: self.elts }
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! iterator {
|
||||
(impl $name:ident -> $elem:ty, $step:expr) => {
|
||||
impl<'self, T> Iterator<$elem> for $name<'self, T> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<$elem> {
|
||||
if self.used >= self.nelts {
|
||||
return None;
|
||||
}
|
||||
let ret = unsafe {
|
||||
match self.vec[self.idx % self.vec.len()] {
|
||||
Some(ref e) => Some(transmute(e)),
|
||||
None => None
|
||||
}
|
||||
};
|
||||
self.idx += $step;
|
||||
self.used += 1;
|
||||
ret
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Deque iterator
|
||||
pub struct DequeIterator<'self, T> {
|
||||
priv idx: uint,
|
||||
priv nelts: uint,
|
||||
priv used: uint,
|
||||
priv vec: &'self [Option<T>]
|
||||
}
|
||||
iterator!{impl DequeIterator -> &'self T, 1}
|
||||
|
||||
/// Deque reverse iterator
|
||||
pub struct DequeRevIterator<'self, T> {
|
||||
priv idx: uint,
|
||||
priv nelts: uint,
|
||||
priv used: uint,
|
||||
priv vec: &'self [Option<T>]
|
||||
}
|
||||
iterator!{impl DequeRevIterator -> &'self T, -1}
|
||||
|
||||
/// Deque mutable iterator
|
||||
pub struct DequeMutIterator<'self, T> {
|
||||
priv idx: uint,
|
||||
priv nelts: uint,
|
||||
priv used: uint,
|
||||
priv vec: &'self mut [Option<T>]
|
||||
|
||||
}
|
||||
iterator!{impl DequeMutIterator -> &'self mut T, 1}
|
||||
|
||||
/// Deque mutable reverse iterator
|
||||
pub struct DequeMutRevIterator<'self, T> {
|
||||
priv idx: uint,
|
||||
priv nelts: uint,
|
||||
priv used: uint,
|
||||
priv vec: &'self mut [Option<T>]
|
||||
}
|
||||
iterator!{impl DequeMutRevIterator -> &'self mut T, -1}
|
||||
|
||||
/// Grow is only called on full elts, so nelts is also len(elts), unlike
|
||||
/// elsewhere.
|
||||
fn grow<T>(nelts: uint, lo: uint, elts: &mut [Option<T>]) -> ~[Option<T>] {
|
||||
|
|
@ -175,9 +253,9 @@ fn get<'r, T>(elts: &'r [Option<T>], i: uint) -> &'r T {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use core::cmp::Eq;
|
||||
use core::kinds::Copy;
|
||||
use core::vec::capacity;
|
||||
use std::cmp::Eq;
|
||||
use std::kinds::Copy;
|
||||
use std::int;
|
||||
|
||||
#[test]
|
||||
fn test_simple() {
|
||||
|
|
@ -318,8 +396,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_param_taggy() {
|
||||
test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3),
|
||||
Two(17, 42));
|
||||
test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -363,11 +440,11 @@ mod tests {
|
|||
let mut d = Deque::new();
|
||||
d.add_back(0u64);
|
||||
d.reserve(50);
|
||||
assert_eq!(capacity(&mut d.elts), 50);
|
||||
assert_eq!(d.elts.capacity(), 50);
|
||||
let mut d = Deque::new();
|
||||
d.add_back(0u32);
|
||||
d.reserve(50);
|
||||
assert_eq!(capacity(&mut d.elts), 50);
|
||||
assert_eq!(d.elts.capacity(), 50);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -375,11 +452,38 @@ mod tests {
|
|||
let mut d = Deque::new();
|
||||
d.add_back(0u64);
|
||||
d.reserve_at_least(50);
|
||||
assert_eq!(capacity(&mut d.elts), 64);
|
||||
assert_eq!(d.elts.capacity(), 64);
|
||||
let mut d = Deque::new();
|
||||
d.add_back(0u32);
|
||||
d.reserve_at_least(50);
|
||||
assert_eq!(capacity(&mut d.elts), 64);
|
||||
assert_eq!(d.elts.capacity(), 64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iter() {
|
||||
let mut d = Deque::new();
|
||||
for int::range(0,5) |i| {
|
||||
d.add_back(i);
|
||||
}
|
||||
assert_eq!(d.iter().collect::<~[&int]>(), ~[&0,&1,&2,&3,&4]);
|
||||
|
||||
for int::range(6,9) |i| {
|
||||
d.add_front(i);
|
||||
}
|
||||
assert_eq!(d.iter().collect::<~[&int]>(), ~[&8,&7,&6,&0,&1,&2,&3,&4]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rev_iter() {
|
||||
let mut d = Deque::new();
|
||||
for int::range(0,5) |i| {
|
||||
d.add_back(i);
|
||||
}
|
||||
assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0]);
|
||||
|
||||
for int::range(6,9) |i| {
|
||||
d.add_front(i);
|
||||
}
|
||||
assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0,&6,&7,&8]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,11 +18,8 @@ Do not use ==, !=, <, etc on doubly-linked lists -- it may not terminate.
|
|||
|
||||
*/
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::managed;
|
||||
use core::old_iter;
|
||||
use core::vec;
|
||||
use std::managed;
|
||||
|
||||
pub type DListLink<T> = Option<@mut DListNode<T>>;
|
||||
|
||||
|
|
@ -213,6 +210,42 @@ impl<T> DList<T> {
|
|||
}
|
||||
|
||||
impl<T> DList<T> {
|
||||
/**
|
||||
* Iterates through the current contents.
|
||||
*
|
||||
* Attempts to access this dlist during iteration are allowed (to
|
||||
* allow for e.g. breadth-first search with in-place enqueues), but
|
||||
* removing the current node is forbidden.
|
||||
*/
|
||||
pub fn each(@mut self, f: &fn(v: &T) -> bool) -> bool {
|
||||
let mut link = self.peek_n();
|
||||
while link.is_some() {
|
||||
let nobe = link.get();
|
||||
assert!(nobe.linked);
|
||||
|
||||
{
|
||||
let frozen_nobe = &*nobe;
|
||||
if !f(&frozen_nobe.data) { return false; }
|
||||
}
|
||||
|
||||
// Check (weakly) that the user didn't do a remove.
|
||||
if self.size == 0 {
|
||||
fail!("The dlist became empty during iteration??")
|
||||
}
|
||||
if !nobe.linked ||
|
||||
(!((nobe.prev.is_some()
|
||||
|| managed::mut_ptr_eq(self.hd.expect("headless dlist?"),
|
||||
nobe))
|
||||
&& (nobe.next.is_some()
|
||||
|| managed::mut_ptr_eq(self.tl.expect("tailless dlist?"),
|
||||
nobe)))) {
|
||||
fail!("Removing a dlist node during iteration is forbidden!")
|
||||
}
|
||||
link = nobe.next_link();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Get the size of the list. O(1).
|
||||
pub fn len(@mut self) -> uint { self.size }
|
||||
/// Returns true if the list is empty. O(1).
|
||||
|
|
@ -484,67 +517,13 @@ impl<T:Copy> DList<T> {
|
|||
|
||||
/// Get data at the list's tail, failing if empty. O(1).
|
||||
pub fn tail(@mut self) -> T { copy self.tail_n().data }
|
||||
|
||||
/// Get the elements of the list as a vector. O(n).
|
||||
pub fn to_vec(@mut self) -> ~[T] {
|
||||
let mut v = vec::with_capacity(self.size);
|
||||
for old_iter::eachi(&self) |index,data| {
|
||||
v[index] = copy *data;
|
||||
}
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> BaseIter<T> for @mut DList<T> {
|
||||
/**
|
||||
* Iterates through the current contents.
|
||||
*
|
||||
* Attempts to access this dlist during iteration are allowed (to
|
||||
* allow for e.g. breadth-first search with in-place enqueues), but
|
||||
* removing the current node is forbidden.
|
||||
*/
|
||||
fn each(&self, f: &fn(v: &T) -> bool) -> bool {
|
||||
let mut link = self.peek_n();
|
||||
while link.is_some() {
|
||||
let nobe = link.get();
|
||||
assert!(nobe.linked);
|
||||
|
||||
{
|
||||
let frozen_nobe = &*nobe;
|
||||
if !f(&frozen_nobe.data) { return false; }
|
||||
}
|
||||
|
||||
// Check (weakly) that the user didn't do a remove.
|
||||
if self.size == 0 {
|
||||
fail!("The dlist became empty during iteration??")
|
||||
}
|
||||
if !nobe.linked ||
|
||||
(!((nobe.prev.is_some()
|
||||
|| managed::mut_ptr_eq(self.hd.expect("headless dlist?"),
|
||||
nobe))
|
||||
&& (nobe.next.is_some()
|
||||
|| managed::mut_ptr_eq(self.tl.expect("tailless dlist?"),
|
||||
nobe)))) {
|
||||
fail!("Removing a dlist node during iteration is forbidden!")
|
||||
}
|
||||
link = nobe.next_link();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> Option<uint> { Some(self.len()) }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use core::prelude::*;
|
||||
|
||||
use super::*;
|
||||
|
||||
use core::old_iter;
|
||||
use core::vec;
|
||||
|
||||
#[test]
|
||||
fn test_dlist_concat() {
|
||||
let a = from_vec([1,2]);
|
||||
|
|
@ -759,11 +738,6 @@ mod tests {
|
|||
assert_eq!(l.len(), 3);
|
||||
}
|
||||
#[test]
|
||||
fn test_dlist_foldl() {
|
||||
let l = from_vec(vec::from_fn(101, |x|x));
|
||||
assert_eq!(old_iter::foldl(&l, 0, |accum,elem| *accum+*elem), 5050);
|
||||
}
|
||||
#[test]
|
||||
fn test_dlist_break_early() {
|
||||
let l = from_vec([1,2,3,4,5]);
|
||||
let mut x = 0;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use std::str;
|
||||
|
||||
// Simple Extensible Binary Markup Language (ebml) reader and writer on a
|
||||
// cursor model. See the specification here:
|
||||
|
|
@ -34,6 +35,20 @@ pub struct Doc {
|
|||
end: uint,
|
||||
}
|
||||
|
||||
impl Doc {
|
||||
pub fn get(&self, tag: uint) -> Doc {
|
||||
reader::get_doc(*self, tag)
|
||||
}
|
||||
|
||||
pub fn as_str_slice<'a>(&'a self) -> &'a str {
|
||||
str::from_bytes_slice(self.data.slice(self.start, self.end))
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> ~str {
|
||||
self.as_str_slice().to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TaggedDoc {
|
||||
tag: uint,
|
||||
doc: Doc,
|
||||
|
|
@ -78,31 +93,21 @@ pub mod reader {
|
|||
|
||||
use serialize;
|
||||
|
||||
use core::prelude::*;
|
||||
use core::cast::transmute;
|
||||
use core::int;
|
||||
use core::io;
|
||||
use core::ptr::offset;
|
||||
use core::str;
|
||||
use core::unstable::intrinsics::bswap32;
|
||||
use core::vec;
|
||||
use std::cast::transmute;
|
||||
use std::int;
|
||||
use std::io;
|
||||
use std::option::{None, Option, Some};
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::ptr::offset;
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::unstable::intrinsics::bswap32;
|
||||
|
||||
// ebml reading
|
||||
|
||||
impl Doc {
|
||||
pub fn get(&self, tag: uint) -> Doc {
|
||||
get_doc(*self, tag)
|
||||
}
|
||||
|
||||
pub fn as_str_slice<'a>(&'a self) -> &'a str {
|
||||
str::from_bytes_slice(self.data.slice(self.start, self.end))
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> ~str {
|
||||
self.as_str_slice().to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
struct Res {
|
||||
val: uint,
|
||||
next: uint
|
||||
|
|
@ -248,7 +253,7 @@ pub mod reader {
|
|||
}
|
||||
|
||||
pub fn with_doc_data<T>(d: Doc, f: &fn(x: &[u8]) -> T) -> T {
|
||||
f(vec::slice(*d.data, d.start, d.end))
|
||||
f(d.data.slice(d.start, d.end))
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -372,7 +377,7 @@ pub mod reader {
|
|||
fn read_u8 (&mut self) -> u8 { doc_as_u8 (self.next_doc(EsU8 )) }
|
||||
fn read_uint(&mut self) -> uint {
|
||||
let v = doc_as_u64(self.next_doc(EsUint));
|
||||
if v > (::core::uint::max_value as u64) {
|
||||
if v > (::std::uint::max_value as u64) {
|
||||
fail!("uint %? too large for this architecture", v);
|
||||
}
|
||||
v as uint
|
||||
|
|
@ -605,8 +610,8 @@ pub mod reader {
|
|||
pub mod writer {
|
||||
use super::*;
|
||||
|
||||
use core::cast;
|
||||
use core::io;
|
||||
use std::cast;
|
||||
use std::io;
|
||||
|
||||
// ebml writing
|
||||
pub struct Encoder {
|
||||
|
|
@ -951,8 +956,8 @@ mod tests {
|
|||
use serialize::Encodable;
|
||||
use serialize;
|
||||
|
||||
use core::io;
|
||||
use core::option::{None, Option, Some};
|
||||
use std::io;
|
||||
use std::option::{None, Option, Some};
|
||||
|
||||
#[test]
|
||||
fn test_option_int() {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ Rust extras are part of the standard Rust distribution.
|
|||
*/
|
||||
|
||||
#[link(name = "extra",
|
||||
vers = "0.7-pre",
|
||||
vers = "0.7",
|
||||
uuid = "122bed0b-c19b-4b82-b0b7-7ae8aead7297",
|
||||
url = "https://github.com/mozilla/rust/tree/master/src/libextra")];
|
||||
|
||||
|
|
@ -32,13 +32,9 @@ Rust extras are part of the standard Rust distribution.
|
|||
#[deny(non_camel_case_types)];
|
||||
#[deny(missing_doc)];
|
||||
|
||||
#[no_std];
|
||||
use std::str::{StrSlice, OwnedStr};
|
||||
|
||||
extern mod core(name = "std", vers = "0.7-pre");
|
||||
|
||||
use core::str::{StrSlice, OwnedStr};
|
||||
|
||||
pub use core::os;
|
||||
pub use std::os;
|
||||
|
||||
pub mod uv_ll;
|
||||
|
||||
|
|
@ -86,13 +82,20 @@ pub mod sort;
|
|||
pub mod dlist;
|
||||
pub mod treemap;
|
||||
|
||||
// Crypto
|
||||
#[path="crypto/digest.rs"]
|
||||
pub mod digest;
|
||||
#[path="crypto/sha1.rs"]
|
||||
pub mod sha1;
|
||||
#[path="crypto/sha2.rs"]
|
||||
pub mod sha2;
|
||||
|
||||
// And ... other stuff
|
||||
|
||||
pub mod ebml;
|
||||
pub mod dbg;
|
||||
pub mod getopts;
|
||||
pub mod json;
|
||||
pub mod sha1;
|
||||
pub mod md4;
|
||||
pub mod tempfile;
|
||||
pub mod term;
|
||||
|
|
@ -128,21 +131,16 @@ pub mod serialize;
|
|||
// 'extra' so that macro-expanded references to extra::serialize and such
|
||||
// can be resolved within libextra.
|
||||
#[doc(hidden)]
|
||||
pub mod std {
|
||||
pub mod extra {
|
||||
pub use serialize;
|
||||
pub use test;
|
||||
|
||||
// For bootstrapping.
|
||||
pub use core::clone;
|
||||
pub use core::condition;
|
||||
pub use core::cmp;
|
||||
pub use core::sys;
|
||||
pub use core::unstable;
|
||||
pub use core::str;
|
||||
pub use core::os;
|
||||
}
|
||||
#[doc(hidden)]
|
||||
pub mod extra {
|
||||
pub use serialize;
|
||||
pub use test;
|
||||
pub use std::clone;
|
||||
pub use std::condition;
|
||||
pub use std::cmp;
|
||||
pub use std::sys;
|
||||
pub use std::unstable;
|
||||
pub use std::str;
|
||||
pub use std::os;
|
||||
}
|
||||
|
|
@ -57,14 +57,14 @@ For more complicated uses (e.g. if one needs to pause iteration and
|
|||
resume it later), a `FileInput` instance can be constructed via the
|
||||
`from_vec`, `from_vec_raw` and `from_args` functions.
|
||||
|
||||
Once created, the `each_line` (from the `core::io::ReaderUtil` trait)
|
||||
Once created, the `each_line` (from the `std::io::ReaderUtil` trait)
|
||||
and `each_line_state` methods allow one to iterate on the lines; the
|
||||
latter provides more information about the position within the
|
||||
iteration to the caller.
|
||||
|
||||
It is possible (and safe) to skip lines and files using the
|
||||
`read_line` and `next_file` methods. Also, `FileInput` implements
|
||||
`core::io::Reader`, and the state will be updated correctly while
|
||||
`std::io::Reader`, and the state will be updated correctly while
|
||||
using any of those methods.
|
||||
|
||||
E.g. the following program reads until an empty line, pauses for user
|
||||
|
|
@ -96,12 +96,10 @@ total line count).
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::io::ReaderUtil;
|
||||
use core::io;
|
||||
use core::os;
|
||||
use core::vec;
|
||||
use std::io::ReaderUtil;
|
||||
use std::io;
|
||||
use std::os;
|
||||
|
||||
/**
|
||||
A summary of the internal state of a `FileInput` object. `line_num`
|
||||
|
|
@ -354,13 +352,13 @@ a literal `-`.
|
|||
*/
|
||||
// XXX: stupid, unclear name
|
||||
pub fn pathify(vec: &[~str], stdin_hyphen : bool) -> ~[Option<Path>] {
|
||||
vec::map(vec, |&str : & ~str| {
|
||||
if stdin_hyphen && str == ~"-" {
|
||||
vec.iter().transform(|str| {
|
||||
if stdin_hyphen && "-" == *str {
|
||||
None
|
||||
} else {
|
||||
Some(Path(str))
|
||||
Some(Path(*str))
|
||||
}
|
||||
})
|
||||
}).collect()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -410,18 +408,17 @@ pub fn input_vec_state(files: ~[Option<Path>],
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use core::prelude::*;
|
||||
|
||||
use super::{FileInput, pathify, input_vec, input_vec_state};
|
||||
|
||||
use core::io;
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use std::io;
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
|
||||
fn make_file(path : &Path, contents: &[~str]) {
|
||||
let file = io::file_writer(path, [io::Create, io::Truncate]).get();
|
||||
|
||||
for contents.each |&str| {
|
||||
for contents.iter().advance |&str| {
|
||||
file.write_str(str);
|
||||
file.write_char('\n');
|
||||
}
|
||||
|
|
@ -448,7 +445,7 @@ mod test {
|
|||
|i| fmt!("tmp/lib-fileinput-test-fileinput-read-byte-%u.tmp", i)), true);
|
||||
|
||||
// 3 files containing 0\n, 1\n, and 2\n respectively
|
||||
for filenames.eachi |i, &filename| {
|
||||
for filenames.iter().enumerate().advance |(i, &filename)| {
|
||||
make_file(filename.get_ref(), [fmt!("%u", i)]);
|
||||
}
|
||||
|
||||
|
|
@ -478,7 +475,7 @@ mod test {
|
|||
|i| fmt!("tmp/lib-fileinput-test-fileinput-read-%u.tmp", i)), true);
|
||||
|
||||
// 3 files containing 1\n, 2\n, and 3\n respectively
|
||||
for filenames.eachi |i, &filename| {
|
||||
for filenames.iter().enumerate().advance |(i, &filename)| {
|
||||
make_file(filename.get_ref(), [fmt!("%u", i)]);
|
||||
}
|
||||
|
||||
|
|
@ -498,7 +495,7 @@ mod test {
|
|||
3,
|
||||
|i| fmt!("tmp/lib-fileinput-test-input-vec-%u.tmp", i)), true);
|
||||
|
||||
for filenames.eachi |i, &filename| {
|
||||
for filenames.iter().enumerate().advance |(i, &filename)| {
|
||||
let contents =
|
||||
vec::from_fn(3, |j| fmt!("%u %u", i, j));
|
||||
make_file(filename.get_ref(), contents);
|
||||
|
|
@ -518,7 +515,7 @@ mod test {
|
|||
3,
|
||||
|i| fmt!("tmp/lib-fileinput-test-input-vec-state-%u.tmp", i)),true);
|
||||
|
||||
for filenames.eachi |i, &filename| {
|
||||
for filenames.iter().enumerate().advance |(i, &filename)| {
|
||||
let contents =
|
||||
vec::from_fn(3, |j| fmt!("%u %u", i, j + 1));
|
||||
make_file(filename.get_ref(), contents);
|
||||
|
|
@ -582,7 +579,7 @@ mod test {
|
|||
3,
|
||||
|i| fmt!("tmp/lib-fileinput-test-next-file-%u.tmp", i)),true);
|
||||
|
||||
for filenames.eachi |i, &filename| {
|
||||
for filenames.iter().enumerate().advance |(i, &filename)| {
|
||||
let contents =
|
||||
vec::from_fn(3, |j| fmt!("%u %u", i, j + 1));
|
||||
make_file(&filename.get(), contents);
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@ Simple compression
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::libc::{c_void, size_t, c_int};
|
||||
use core::libc;
|
||||
use core::vec;
|
||||
use std::libc::{c_void, size_t, c_int};
|
||||
use std::libc;
|
||||
use std::vec;
|
||||
|
||||
pub mod rustrt {
|
||||
use core::libc::{c_int, c_void, size_t};
|
||||
use std::libc::{c_int, c_void, size_t};
|
||||
|
||||
#[link_name = "rustrt"]
|
||||
pub extern {
|
||||
|
|
@ -44,8 +44,8 @@ static lz_fast : c_int = 0x1; // LZ with only one probe
|
|||
static lz_norm : c_int = 0x80; // LZ with 128 probes, "normal"
|
||||
static lz_best : c_int = 0xfff; // LZ with 4095 probes, "best"
|
||||
|
||||
pub fn deflate_bytes(bytes: &const [u8]) -> ~[u8] {
|
||||
do vec::as_const_buf(bytes) |b, len| {
|
||||
pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] {
|
||||
do vec::as_imm_buf(bytes) |b, len| {
|
||||
unsafe {
|
||||
let mut outsz : size_t = 0;
|
||||
let res =
|
||||
|
|
@ -62,8 +62,8 @@ pub fn deflate_bytes(bytes: &const [u8]) -> ~[u8] {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn inflate_bytes(bytes: &const [u8]) -> ~[u8] {
|
||||
do vec::as_const_buf(bytes) |b, len| {
|
||||
pub fn inflate_bytes(bytes: &[u8]) -> ~[u8] {
|
||||
do vec::as_imm_buf(bytes) |b, len| {
|
||||
unsafe {
|
||||
let mut outsz : size_t = 0;
|
||||
let res =
|
||||
|
|
@ -83,9 +83,8 @@ pub fn inflate_bytes(bytes: &const [u8]) -> ~[u8] {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use core::rand;
|
||||
use core::rand::RngUtil;
|
||||
use core::prelude::*;
|
||||
use std::rand;
|
||||
use std::rand::RngUtil;
|
||||
|
||||
#[test]
|
||||
#[allow(non_implicitly_copyable_typarams)]
|
||||
|
|
|
|||
|
|
@ -49,14 +49,13 @@ block the scheduler thread, so will their pipes.
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
// The basic send/recv interface FlatChan and PortChan will implement
|
||||
use core::io;
|
||||
use core::comm::GenericChan;
|
||||
use core::comm::GenericPort;
|
||||
use core::sys::size_of;
|
||||
use core::vec;
|
||||
use std::io;
|
||||
use std::comm::GenericChan;
|
||||
use std::comm::GenericPort;
|
||||
use std::sys::size_of;
|
||||
use std::vec;
|
||||
|
||||
/**
|
||||
A FlatPort, consisting of a `BytePort` that receives byte vectors,
|
||||
|
|
@ -95,9 +94,9 @@ pub mod serial {
|
|||
use flatpipes::bytepipes::{PipeBytePort, PipeByteChan};
|
||||
use flatpipes::{FlatPort, FlatChan};
|
||||
|
||||
use core::io::{Reader, Writer};
|
||||
use core::comm::{Port, Chan};
|
||||
use core::comm;
|
||||
use std::io::{Reader, Writer};
|
||||
use std::comm::{Port, Chan};
|
||||
use std::comm;
|
||||
|
||||
pub type ReaderPort<T, R> = FlatPort<
|
||||
T, DeserializingUnflattener<DefaultDecoder, T>,
|
||||
|
|
@ -166,22 +165,21 @@ Constructors for flat pipes that send POD types using memcpy.
|
|||
|
||||
# Safety Note
|
||||
|
||||
This module is currently unsafe because it uses `Copy Owned` as a type
|
||||
parameter bounds meaning POD (plain old data), but `Copy Owned` and
|
||||
This module is currently unsafe because it uses `Copy Send` as a type
|
||||
parameter bounds meaning POD (plain old data), but `Copy Send` and
|
||||
POD are not equivelant.
|
||||
|
||||
*/
|
||||
pub mod pod {
|
||||
use core::prelude::*;
|
||||
|
||||
use flatpipes::flatteners::{PodUnflattener, PodFlattener};
|
||||
use flatpipes::bytepipes::{ReaderBytePort, WriterByteChan};
|
||||
use flatpipes::bytepipes::{PipeBytePort, PipeByteChan};
|
||||
use flatpipes::{FlatPort, FlatChan};
|
||||
|
||||
use core::io::{Reader, Writer};
|
||||
use core::comm::{Port, Chan};
|
||||
use core::comm;
|
||||
use std::io::{Reader, Writer};
|
||||
use std::comm::{Port, Chan};
|
||||
use std::comm;
|
||||
|
||||
pub type ReaderPort<T, R> =
|
||||
FlatPort<T, PodUnflattener<T>, ReaderBytePort<R>>;
|
||||
|
|
@ -191,7 +189,7 @@ pub mod pod {
|
|||
pub type PipeChan<T> = FlatChan<T, PodFlattener<T>, PipeByteChan>;
|
||||
|
||||
/// Create a `FlatPort` from a `Reader`
|
||||
pub fn reader_port<T:Copy + Owned,R:Reader>(
|
||||
pub fn reader_port<T:Copy + Send,R:Reader>(
|
||||
reader: R
|
||||
) -> ReaderPort<T, R> {
|
||||
let unflat: PodUnflattener<T> = PodUnflattener::new();
|
||||
|
|
@ -200,7 +198,7 @@ pub mod pod {
|
|||
}
|
||||
|
||||
/// Create a `FlatChan` from a `Writer`
|
||||
pub fn writer_chan<T:Copy + Owned,W:Writer>(
|
||||
pub fn writer_chan<T:Copy + Send,W:Writer>(
|
||||
writer: W
|
||||
) -> WriterChan<T, W> {
|
||||
let flat: PodFlattener<T> = PodFlattener::new();
|
||||
|
|
@ -209,21 +207,21 @@ pub mod pod {
|
|||
}
|
||||
|
||||
/// Create a `FlatPort` from a `Port<~[u8]>`
|
||||
pub fn pipe_port<T:Copy + Owned>(port: Port<~[u8]>) -> PipePort<T> {
|
||||
pub fn pipe_port<T:Copy + Send>(port: Port<~[u8]>) -> PipePort<T> {
|
||||
let unflat: PodUnflattener<T> = PodUnflattener::new();
|
||||
let byte_port = PipeBytePort::new(port);
|
||||
FlatPort::new(unflat, byte_port)
|
||||
}
|
||||
|
||||
/// Create a `FlatChan` from a `Chan<~[u8]>`
|
||||
pub fn pipe_chan<T:Copy + Owned>(chan: Chan<~[u8]>) -> PipeChan<T> {
|
||||
pub fn pipe_chan<T:Copy + Send>(chan: Chan<~[u8]>) -> PipeChan<T> {
|
||||
let flat: PodFlattener<T> = PodFlattener::new();
|
||||
let byte_chan = PipeByteChan::new(chan);
|
||||
FlatChan::new(flat, byte_chan)
|
||||
}
|
||||
|
||||
/// Create a pair of `FlatChan` and `FlatPort`, backed by pipes
|
||||
pub fn pipe_stream<T:Copy + Owned>() -> (PipePort<T>, PipeChan<T>) {
|
||||
pub fn pipe_stream<T:Copy + Send>() -> (PipePort<T>, PipeChan<T>) {
|
||||
let (port, chan) = comm::stream();
|
||||
return (pipe_port(port), pipe_chan(chan));
|
||||
}
|
||||
|
|
@ -307,11 +305,11 @@ impl<T,U:Unflattener<T>,P:BytePort> GenericPort<T> for FlatPort<T, U, P> {
|
|||
|
||||
impl<T,F:Flattener<T>,C:ByteChan> GenericChan<T> for FlatChan<T, F, C> {
|
||||
fn send(&self, val: T) {
|
||||
self.byte_chan.send(CONTINUE.to_vec());
|
||||
self.byte_chan.send(CONTINUE.to_owned());
|
||||
let bytes = self.flattener.flatten(val);
|
||||
let len = bytes.len() as u64;
|
||||
do io::u64_to_be_bytes(len, size_of::<u64>()) |len_bytes| {
|
||||
self.byte_chan.send(len_bytes.to_vec());
|
||||
self.byte_chan.send(len_bytes.to_owned());
|
||||
}
|
||||
self.byte_chan.send(bytes);
|
||||
}
|
||||
|
|
@ -337,7 +335,6 @@ impl<T,F:Flattener<T>,C:ByteChan> FlatChan<T, F, C> {
|
|||
|
||||
|
||||
pub mod flatteners {
|
||||
use core::prelude::*;
|
||||
|
||||
use ebml;
|
||||
use flatpipes::{Flattener, Unflattener};
|
||||
|
|
@ -345,14 +342,14 @@ pub mod flatteners {
|
|||
use json;
|
||||
use serialize::{Encoder, Decoder, Encodable, Decodable};
|
||||
|
||||
use core::cast;
|
||||
use core::io::{Writer, Reader, ReaderUtil};
|
||||
use core::io;
|
||||
use core::ptr;
|
||||
use core::sys::size_of;
|
||||
use core::vec;
|
||||
use std::cast;
|
||||
use std::io::{Writer, Reader, ReaderUtil};
|
||||
use std::io;
|
||||
use std::ptr;
|
||||
use std::sys::size_of;
|
||||
use std::vec;
|
||||
|
||||
// FIXME #4074: Copy + Owned != POD
|
||||
// FIXME #4074: Copy + Send != POD
|
||||
pub struct PodUnflattener<T> {
|
||||
bogus: ()
|
||||
}
|
||||
|
|
@ -361,7 +358,7 @@ pub mod flatteners {
|
|||
bogus: ()
|
||||
}
|
||||
|
||||
impl<T:Copy + Owned> Unflattener<T> for PodUnflattener<T> {
|
||||
impl<T:Copy + Send> Unflattener<T> for PodUnflattener<T> {
|
||||
fn unflatten(&self, buf: ~[u8]) -> T {
|
||||
assert!(size_of::<T>() != 0);
|
||||
assert_eq!(size_of::<T>(), buf.len());
|
||||
|
|
@ -371,7 +368,7 @@ pub mod flatteners {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Owned> Flattener<T> for PodFlattener<T> {
|
||||
impl<T:Copy + Send> Flattener<T> for PodFlattener<T> {
|
||||
fn flatten(&self, val: T) -> ~[u8] {
|
||||
assert!(size_of::<T>() != 0);
|
||||
let val: *T = ptr::to_unsafe_ptr(&val);
|
||||
|
|
@ -380,7 +377,7 @@ pub mod flatteners {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Owned> PodUnflattener<T> {
|
||||
impl<T:Copy + Send> PodUnflattener<T> {
|
||||
pub fn new() -> PodUnflattener<T> {
|
||||
PodUnflattener {
|
||||
bogus: ()
|
||||
|
|
@ -388,7 +385,7 @@ pub mod flatteners {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Owned> PodFlattener<T> {
|
||||
impl<T:Copy + Send> PodFlattener<T> {
|
||||
pub fn new() -> PodFlattener<T> {
|
||||
PodFlattener {
|
||||
bogus: ()
|
||||
|
|
@ -509,13 +506,12 @@ pub mod flatteners {
|
|||
}
|
||||
|
||||
pub mod bytepipes {
|
||||
use core::prelude::*;
|
||||
|
||||
use flatpipes::{ByteChan, BytePort};
|
||||
|
||||
use core::comm::{Port, Chan};
|
||||
use core::comm;
|
||||
use core::io::{Writer, Reader, ReaderUtil};
|
||||
use std::comm::{Port, Chan};
|
||||
use std::comm;
|
||||
use std::io::{Writer, Reader, ReaderUtil};
|
||||
|
||||
pub struct ReaderBytePort<R> {
|
||||
reader: R
|
||||
|
|
@ -583,12 +579,12 @@ pub mod bytepipes {
|
|||
impl BytePort for PipeBytePort {
|
||||
fn try_recv(&self, count: uint) -> Option<~[u8]> {
|
||||
if self.buf.len() >= count {
|
||||
let mut bytes = ::core::util::replace(&mut *self.buf, ~[]);
|
||||
let mut bytes = ::std::util::replace(&mut *self.buf, ~[]);
|
||||
*self.buf = bytes.slice(count, bytes.len()).to_owned();
|
||||
bytes.truncate(count);
|
||||
return Some(bytes);
|
||||
} else if !self.buf.is_empty() {
|
||||
let mut bytes = ::core::util::replace(&mut *self.buf, ~[]);
|
||||
let mut bytes = ::std::util::replace(&mut *self.buf, ~[]);
|
||||
assert!(count > bytes.len());
|
||||
match self.try_recv(count - bytes.len()) {
|
||||
Some(rest) => {
|
||||
|
|
@ -637,7 +633,6 @@ pub mod bytepipes {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use core::prelude::*;
|
||||
|
||||
use flatpipes::{Flattener, Unflattener};
|
||||
use flatpipes::bytepipes::*;
|
||||
|
|
@ -647,11 +642,11 @@ mod test {
|
|||
use flatpipes::{BytePort, FlatChan, FlatPort};
|
||||
use net::tcp::TcpSocketBuf;
|
||||
|
||||
use core::comm;
|
||||
use core::int;
|
||||
use core::io::BytesWriter;
|
||||
use core::result;
|
||||
use core::task;
|
||||
use std::comm;
|
||||
use std::int;
|
||||
use std::io::BytesWriter;
|
||||
use std::result;
|
||||
use std::task;
|
||||
|
||||
#[test]
|
||||
#[ignore(reason = "ebml failure")]
|
||||
|
|
@ -772,7 +767,7 @@ mod test {
|
|||
writer_chan: WriterChanFactory<F>,
|
||||
port: uint) {
|
||||
|
||||
use core::cell::Cell;
|
||||
use std::cell::Cell;
|
||||
use net::ip;
|
||||
use net::tcp;
|
||||
use uv;
|
||||
|
|
@ -871,17 +866,16 @@ mod test {
|
|||
// Tests that the different backends behave the same when the
|
||||
// binary streaming protocol is broken
|
||||
mod broken_protocol {
|
||||
use core::prelude::*;
|
||||
|
||||
use flatpipes::{BytePort, FlatPort};
|
||||
use flatpipes::flatteners::PodUnflattener;
|
||||
use flatpipes::pod;
|
||||
use io_util::BufReader;
|
||||
|
||||
use core::comm;
|
||||
use core::io;
|
||||
use core::sys;
|
||||
use core::task;
|
||||
use std::comm;
|
||||
use std::io;
|
||||
use std::sys;
|
||||
use std::task;
|
||||
|
||||
type PortLoader<P> =
|
||||
~fn(~[u8]) -> FlatPort<int, PodUnflattener<int>, P>;
|
||||
|
|
@ -937,7 +931,7 @@ mod test {
|
|||
fn test_try_recv_none3<P:BytePort>(loader: PortLoader<P>) {
|
||||
static CONTINUE: [u8, ..4] = [0xAA, 0xBB, 0xCC, 0xDD];
|
||||
// The control word is followed by garbage
|
||||
let bytes = CONTINUE.to_vec() + [0];
|
||||
let bytes = CONTINUE.to_owned() + [0];
|
||||
let port = loader(bytes);
|
||||
let res: Option<int> = port.try_recv();
|
||||
assert!(res.is_none());
|
||||
|
|
@ -959,9 +953,9 @@ mod test {
|
|||
// then undeserializable garbage
|
||||
let len_bytes = do io::u64_to_be_bytes(
|
||||
1, sys::size_of::<u64>()) |len_bytes| {
|
||||
len_bytes.to_vec()
|
||||
len_bytes.to_owned()
|
||||
};
|
||||
let bytes = CONTINUE.to_vec() + len_bytes + [0, 0, 0, 0];
|
||||
let bytes = CONTINUE.to_owned() + len_bytes + [0, 0, 0, 0];
|
||||
|
||||
let port = loader(bytes);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,9 @@
|
|||
* of features.
|
||||
*/
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::cmp::{Eq, Ord};
|
||||
use core::option::{Some, None};
|
||||
use std::cmp::{Eq, Ord};
|
||||
use std::option::{Some, None};
|
||||
|
||||
pub type Treemap<K, V> = @TreeNode<K, V>;
|
||||
|
||||
|
|
@ -66,9 +65,9 @@ pub fn traverse<K, V: Copy>(m: Treemap<K, V>, f: &fn(&K, &V)) {
|
|||
// matches to me, so I changed it. but that may be a
|
||||
// de-optimization -- tjc
|
||||
Node(@ref k, @ref v, left, right) => {
|
||||
traverse(left, f);
|
||||
traverse(left, |k,v| f(k,v));
|
||||
f(k, v);
|
||||
traverse(right, f);
|
||||
traverse(right, |k,v| f(k,v));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* ~~~ {.rust}
|
||||
* # fn fib(n: uint) -> uint {42};
|
||||
* # fn make_a_sandwich() {};
|
||||
* let mut delayed_fib = std::future::spawn (|| fib(5000) );
|
||||
* let mut delayed_fib = extra::future::spawn (|| fib(5000) );
|
||||
* make_a_sandwich();
|
||||
* println(fmt!("fib(5000) = %?", delayed_fib.get()))
|
||||
* ~~~
|
||||
|
|
@ -25,13 +25,12 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::cast;
|
||||
use core::cell::Cell;
|
||||
use core::comm::{PortOne, oneshot, send_one, recv_one};
|
||||
use core::task;
|
||||
use core::util::replace;
|
||||
use std::cast;
|
||||
use std::cell::Cell;
|
||||
use std::comm::{PortOne, oneshot, send_one, recv_one};
|
||||
use std::task;
|
||||
use std::util::replace;
|
||||
|
||||
#[doc = "The future type"]
|
||||
pub struct Future<A> {
|
||||
|
|
@ -44,7 +43,7 @@ pub struct Future<A> {
|
|||
// over ~fn's that have pipes and so forth within!
|
||||
#[unsafe_destructor]
|
||||
impl<A> Drop for Future<A> {
|
||||
fn finalize(&self) {}
|
||||
fn drop(&self) {}
|
||||
}
|
||||
|
||||
priv enum FutureState<A> {
|
||||
|
|
@ -101,7 +100,7 @@ pub fn from_value<A>(val: A) -> Future<A> {
|
|||
Future {state: Forced(val)}
|
||||
}
|
||||
|
||||
pub fn from_port<A:Owned>(port: PortOne<A>) -> Future<A> {
|
||||
pub fn from_port<A:Send>(port: PortOne<A>) -> Future<A> {
|
||||
/*!
|
||||
* Create a future from a port
|
||||
*
|
||||
|
|
@ -127,7 +126,7 @@ pub fn from_fn<A>(f: ~fn() -> A) -> Future<A> {
|
|||
Future {state: Pending(f)}
|
||||
}
|
||||
|
||||
pub fn spawn<A:Owned>(blk: ~fn() -> A) -> Future<A> {
|
||||
pub fn spawn<A:Send>(blk: ~fn() -> A) -> Future<A> {
|
||||
/*!
|
||||
* Create a future from a unique closure.
|
||||
*
|
||||
|
|
@ -151,9 +150,9 @@ pub fn spawn<A:Owned>(blk: ~fn() -> A) -> Future<A> {
|
|||
mod test {
|
||||
use future::*;
|
||||
|
||||
use core::cell::Cell;
|
||||
use core::comm::{oneshot, send_one};
|
||||
use core::task;
|
||||
use std::cell::Cell;
|
||||
use std::comm::{oneshot, send_one};
|
||||
use std::task;
|
||||
|
||||
#[test]
|
||||
fn test_from_value() {
|
||||
|
|
|
|||
|
|
@ -81,14 +81,13 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::cmp::Eq;
|
||||
use core::result::{Err, Ok};
|
||||
use core::result;
|
||||
use core::option::{Some, None};
|
||||
use core::str;
|
||||
use core::vec;
|
||||
use std::cmp::Eq;
|
||||
use std::result::{Err, Ok};
|
||||
use std::result;
|
||||
use std::option::{Some, None};
|
||||
use std::str;
|
||||
use std::vec;
|
||||
|
||||
#[deriving(Eq)]
|
||||
pub enum Name {
|
||||
|
|
@ -177,7 +176,7 @@ fn name_str(nm: &Name) -> ~str {
|
|||
}
|
||||
|
||||
fn find_opt(opts: &[Opt], nm: Name) -> Option<uint> {
|
||||
vec::position(opts, |opt| opt.name == nm)
|
||||
opts.iter().position_(|opt| opt.name == nm)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -295,7 +294,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
|
|||
}
|
||||
}
|
||||
let mut name_pos = 0;
|
||||
for names.each() |nm| {
|
||||
for names.iter().advance() |nm| {
|
||||
name_pos += 1;
|
||||
let optid = match find_opt(opts, copy *nm) {
|
||||
Some(id) => id,
|
||||
|
|
@ -373,7 +372,7 @@ pub fn opt_count(mm: &Matches, nm: &str) -> uint {
|
|||
|
||||
/// Returns true if any of several options were matched
|
||||
pub fn opts_present(mm: &Matches, names: &[~str]) -> bool {
|
||||
for names.each |nm| {
|
||||
for names.iter().advance |nm| {
|
||||
match find_opt(mm.opts, mkname(*nm)) {
|
||||
Some(id) if !mm.vals[id].is_empty() => return true,
|
||||
_ => (),
|
||||
|
|
@ -400,7 +399,7 @@ pub fn opt_str(mm: &Matches, nm: &str) -> ~str {
|
|||
* option took an argument
|
||||
*/
|
||||
pub fn opts_str(mm: &Matches, names: &[~str]) -> ~str {
|
||||
for names.each |nm| {
|
||||
for names.iter().advance |nm| {
|
||||
match opt_val(mm, *nm) {
|
||||
Val(ref s) => return copy *s,
|
||||
_ => ()
|
||||
|
|
@ -418,10 +417,11 @@ pub fn opts_str(mm: &Matches, names: &[~str]) -> ~str {
|
|||
*/
|
||||
pub fn opt_strs(mm: &Matches, nm: &str) -> ~[~str] {
|
||||
let mut acc: ~[~str] = ~[];
|
||||
for vec::each(opt_vals(mm, nm)) |v| {
|
||||
let r = opt_vals(mm, nm);
|
||||
for r.iter().advance |v| {
|
||||
match *v { Val(ref s) => acc.push(copy *s), _ => () }
|
||||
}
|
||||
return acc;
|
||||
acc
|
||||
}
|
||||
|
||||
/// Returns the string argument supplied to a matching option or none
|
||||
|
|
@ -465,8 +465,8 @@ pub mod groups {
|
|||
use getopts::{HasArg, Long, Maybe, Multi, No, Occur, Opt, Optional, Req};
|
||||
use getopts::{Short, Yes};
|
||||
|
||||
use core::str;
|
||||
use core::vec;
|
||||
use std::str;
|
||||
use std::vec;
|
||||
|
||||
/** one group of options, e.g., both -h and --help, along with
|
||||
* their shared description and properties
|
||||
|
|
@ -592,9 +592,9 @@ pub mod groups {
|
|||
*/
|
||||
pub fn usage(brief: &str, opts: &[OptGroup]) -> ~str {
|
||||
|
||||
let desc_sep = ~"\n" + " ".repeat(24);
|
||||
let desc_sep = "\n" + " ".repeat(24);
|
||||
|
||||
let rows = vec::map(opts, |optref| {
|
||||
let mut rows = opts.iter().transform(|optref| {
|
||||
let OptGroup{short_name: short_name,
|
||||
long_name: long_name,
|
||||
hint: hint,
|
||||
|
|
@ -605,33 +605,47 @@ pub mod groups {
|
|||
let mut row = " ".repeat(4);
|
||||
|
||||
// short option
|
||||
row += match short_name.len() {
|
||||
0 => ~"",
|
||||
1 => ~"-" + short_name + " ",
|
||||
match short_name.len() {
|
||||
0 => {}
|
||||
1 => {
|
||||
row.push_char('-');
|
||||
row.push_str(short_name);
|
||||
row.push_char(' ');
|
||||
}
|
||||
_ => fail!("the short name should only be 1 ascii char long"),
|
||||
};
|
||||
}
|
||||
|
||||
// long option
|
||||
row += match long_name.len() {
|
||||
0 => ~"",
|
||||
_ => ~"--" + long_name + " ",
|
||||
};
|
||||
match long_name.len() {
|
||||
0 => {}
|
||||
_ => {
|
||||
row.push_str("--");
|
||||
row.push_str(long_name);
|
||||
row.push_char(' ');
|
||||
}
|
||||
}
|
||||
|
||||
// arg
|
||||
row += match hasarg {
|
||||
No => ~"",
|
||||
Yes => hint,
|
||||
Maybe => ~"[" + hint + "]",
|
||||
};
|
||||
match hasarg {
|
||||
No => {}
|
||||
Yes => row.push_str(hint),
|
||||
Maybe => {
|
||||
row.push_char('[');
|
||||
row.push_str(hint);
|
||||
row.push_char(']');
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: #5516
|
||||
// here we just need to indent the start of the description
|
||||
let rowlen = row.len();
|
||||
row += if rowlen < 24 {
|
||||
" ".repeat(24 - rowlen)
|
||||
if rowlen < 24 {
|
||||
for (24 - rowlen).times {
|
||||
row.push_char(' ')
|
||||
}
|
||||
} else {
|
||||
copy desc_sep
|
||||
};
|
||||
row.push_str(desc_sep)
|
||||
}
|
||||
|
||||
// Normalize desc to contain words separated by one space character
|
||||
let mut desc_normalized_whitespace = ~"";
|
||||
|
|
@ -648,14 +662,14 @@ pub mod groups {
|
|||
|
||||
// FIXME: #5516
|
||||
// wrapped description
|
||||
row += desc_rows.connect(desc_sep);
|
||||
row.push_str(desc_rows.connect(desc_sep));
|
||||
|
||||
row
|
||||
});
|
||||
|
||||
return str::to_owned(brief) +
|
||||
"\n\nOptions:\n" +
|
||||
rows.connect("\n") +
|
||||
rows.collect::<~[~str]>().connect("\n") +
|
||||
"\n\n";
|
||||
}
|
||||
} // end groups module
|
||||
|
|
@ -666,8 +680,8 @@ mod tests {
|
|||
use getopts::groups::OptGroup;
|
||||
use getopts::*;
|
||||
|
||||
use core::result::{Err, Ok};
|
||||
use core::result;
|
||||
use std::result::{Err, Ok};
|
||||
use std::result;
|
||||
|
||||
fn check_fail_type(f: Fail_, ft: FailType) {
|
||||
match f {
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::io::{Reader, BytesReader};
|
||||
use core::io;
|
||||
use std::io::{Reader, BytesReader};
|
||||
use std::io;
|
||||
use std::cast;
|
||||
|
||||
/// An implementation of the io::Reader interface which reads a buffer of bytes
|
||||
pub struct BufReader {
|
||||
|
|
@ -29,10 +30,13 @@ impl BufReader {
|
|||
}
|
||||
|
||||
fn as_bytes_reader<A>(&self, f: &fn(&BytesReader) -> A) -> A {
|
||||
// XXX FIXME(#5723)
|
||||
let bytes = ::std::util::id::<&[u8]>(self.buf);
|
||||
let bytes: &'static [u8] = unsafe { cast::transmute(bytes) };
|
||||
// Recreating the BytesReader state every call since
|
||||
// I can't get the borrowing to work correctly
|
||||
let bytes_reader = BytesReader {
|
||||
bytes: ::core::util::id::<&[u8]>(self.buf),
|
||||
bytes: bytes,
|
||||
pos: @mut *self.pos
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -16,16 +16,15 @@
|
|||
|
||||
//! json serialization
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::char;
|
||||
use core::float;
|
||||
use core::hashmap::HashMap;
|
||||
use core::io::{WriterUtil, ReaderUtil};
|
||||
use core::io;
|
||||
use core::str;
|
||||
use core::to_str;
|
||||
use core::vec;
|
||||
use std::char;
|
||||
use std::float;
|
||||
use std::hashmap::HashMap;
|
||||
use std::io::{WriterUtil, ReaderUtil};
|
||||
use std::io;
|
||||
use std::str;
|
||||
use std::to_str;
|
||||
use std::vec;
|
||||
|
||||
use serialize::Encodable;
|
||||
use serialize;
|
||||
|
|
@ -60,25 +59,27 @@ fn escape_str(s: &str) -> ~str {
|
|||
let mut escaped = ~"\"";
|
||||
for s.iter().advance |c| {
|
||||
match c {
|
||||
'"' => escaped += "\\\"",
|
||||
'\\' => escaped += "\\\\",
|
||||
'\x08' => escaped += "\\b",
|
||||
'\x0c' => escaped += "\\f",
|
||||
'\n' => escaped += "\\n",
|
||||
'\r' => escaped += "\\r",
|
||||
'\t' => escaped += "\\t",
|
||||
_ => escaped += str::from_char(c)
|
||||
'"' => escaped.push_str("\\\""),
|
||||
'\\' => escaped.push_str("\\\\"),
|
||||
'\x08' => escaped.push_str("\\b"),
|
||||
'\x0c' => escaped.push_str("\\f"),
|
||||
'\n' => escaped.push_str("\\n"),
|
||||
'\r' => escaped.push_str("\\r"),
|
||||
'\t' => escaped.push_str("\\t"),
|
||||
_ => escaped.push_char(c),
|
||||
}
|
||||
};
|
||||
|
||||
escaped += "\"";
|
||||
escaped.push_char('"');
|
||||
|
||||
escaped
|
||||
}
|
||||
|
||||
fn spaces(n: uint) -> ~str {
|
||||
let mut ss = ~"";
|
||||
for n.times { ss.push_str(" "); }
|
||||
for n.times {
|
||||
ss.push_str(" ");
|
||||
}
|
||||
return ss;
|
||||
}
|
||||
|
||||
|
|
@ -950,7 +951,7 @@ impl serialize::Decoder for Decoder {
|
|||
}
|
||||
ref json => fail!("invalid variant: %?", *json),
|
||||
};
|
||||
let idx = match vec::position(names, |n| str::eq_slice(*n, name)) {
|
||||
let idx = match names.iter().position_(|n| str::eq_slice(*n, name)) {
|
||||
Some(idx) => idx,
|
||||
None => fail!("Unknown variant name: %?", name),
|
||||
};
|
||||
|
|
@ -1123,7 +1124,7 @@ impl Eq for Json {
|
|||
&Object(ref d1) => {
|
||||
if d0.len() == d1.len() {
|
||||
let mut equal = true;
|
||||
for d0.each |k, v0| {
|
||||
for d0.iter().advance |(k, v0)| {
|
||||
match d1.find(k) {
|
||||
Some(v1) if v0 == v1 => { },
|
||||
_ => { equal = false; break }
|
||||
|
|
@ -1186,12 +1187,12 @@ impl Ord for Json {
|
|||
let mut d1_flat = ~[];
|
||||
|
||||
// FIXME #4430: this is horribly inefficient...
|
||||
for d0.each |k, v| {
|
||||
for d0.iter().advance |(k, v)| {
|
||||
d0_flat.push((@copy *k, @copy *v));
|
||||
}
|
||||
d0_flat.qsort();
|
||||
|
||||
for d1.each |k, v| {
|
||||
for d1.iter().advance |(k, v)| {
|
||||
d1_flat.push((@copy *k, @copy *v));
|
||||
}
|
||||
d1_flat.qsort();
|
||||
|
|
@ -1326,7 +1327,7 @@ impl<A:ToJson> ToJson for ~[A] {
|
|||
impl<A:ToJson + Copy> ToJson for HashMap<~str, A> {
|
||||
fn to_json(&self) -> Json {
|
||||
let mut d = HashMap::new();
|
||||
for self.each |key, value| {
|
||||
for self.iter().advance |(key, value)| {
|
||||
d.insert(copy *key, value.to_json());
|
||||
}
|
||||
Object(~d)
|
||||
|
|
@ -1354,15 +1355,14 @@ impl to_str::ToStr for Error {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use core::prelude::*;
|
||||
|
||||
use super::*;
|
||||
|
||||
use core::hashmap::HashMap;
|
||||
use core::io;
|
||||
use core::result;
|
||||
use std::hashmap::HashMap;
|
||||
use std::io;
|
||||
use std::result;
|
||||
|
||||
use std::serialize::Decodable;
|
||||
use extra::serialize::Decodable;
|
||||
|
||||
#[deriving(Eq, Encodable, Decodable)]
|
||||
enum Animal {
|
||||
|
|
@ -1385,7 +1385,7 @@ mod tests {
|
|||
fn mk_object(items: &[(~str, Json)]) -> Json {
|
||||
let mut d = ~HashMap::new();
|
||||
|
||||
for items.each |item| {
|
||||
for items.iter().advance |item| {
|
||||
match *item {
|
||||
(ref key, ref value) => { d.insert(copy *key, copy *value); },
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
//! A standard, garbage-collected linked list.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
|
||||
#[deriving(Eq)]
|
||||
|
|
@ -181,7 +180,7 @@ mod tests {
|
|||
use list::*;
|
||||
use list;
|
||||
|
||||
use core::option;
|
||||
use std::option;
|
||||
|
||||
#[test]
|
||||
fn test_is_empty() {
|
||||
|
|
|
|||
|
|
@ -8,10 +8,9 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
|
||||
struct Quad {
|
||||
a: u32,
|
||||
|
|
@ -59,7 +58,8 @@ pub fn md4(msg: &[u8]) -> Quad {
|
|||
while i < e {
|
||||
let (aa, bb, cc, dd) = (a, b, c, d);
|
||||
|
||||
let mut (j, base) = (0u, i);
|
||||
let mut j = 0u;
|
||||
let mut base = i;
|
||||
while j < 16u {
|
||||
x[j] = (msg[base] as u32) + (msg[base + 1u] as u32 << 8u32) +
|
||||
(msg[base + 2u] as u32 << 16u32) +
|
||||
|
|
@ -118,8 +118,10 @@ pub fn md4_str(msg: &[u8]) -> ~str {
|
|||
let mut i = 0u32;
|
||||
while i < 4u32 {
|
||||
let byte = (u >> (i * 8u32)) as u8;
|
||||
if byte <= 16u8 { result += "0"; }
|
||||
result += uint::to_str_radix(byte as uint, 16u);
|
||||
if byte <= 16u8 {
|
||||
result.push_char('0')
|
||||
}
|
||||
result.push_str(uint::to_str_radix(byte as uint, 16u));
|
||||
i += 1u32;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,12 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::libc;
|
||||
use core::comm::{stream, SharedChan};
|
||||
use core::ptr;
|
||||
use core::result;
|
||||
use core::str;
|
||||
use std::libc;
|
||||
use std::comm::{stream, SharedChan};
|
||||
use std::ptr;
|
||||
use std::result;
|
||||
use std::str;
|
||||
|
||||
use iotask = uv::iotask::IoTask;
|
||||
use interact = uv::iotask::interact;
|
||||
|
|
@ -55,7 +54,7 @@ pub struct ParseAddrErr {
|
|||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * ip - a `std::net::ip::IpAddr`
|
||||
* * ip - a `extra::net::ip::IpAddr`
|
||||
*/
|
||||
pub fn format_addr(ip: &IpAddr) -> ~str {
|
||||
match *ip {
|
||||
|
|
@ -80,7 +79,7 @@ pub fn format_addr(ip: &IpAddr) -> ~str {
|
|||
* Get the associated port
|
||||
*
|
||||
* # Arguments
|
||||
* * ip - a `std::net::ip::IpAddr`
|
||||
* * ip - a `extra::net::ip::IpAddr`
|
||||
*/
|
||||
pub fn get_port(ip: &IpAddr) -> uint {
|
||||
match *ip {
|
||||
|
|
@ -149,16 +148,15 @@ pub fn get_addr(node: &str, iotask: &iotask)
|
|||
}
|
||||
|
||||
pub mod v4 {
|
||||
use core::prelude::*;
|
||||
|
||||
use net::ip::{IpAddr, Ipv4, ParseAddrErr};
|
||||
use uv::ll;
|
||||
use uv_ip4_addr = uv::ll::ip4_addr;
|
||||
use uv_ip4_name = uv::ll::ip4_name;
|
||||
|
||||
use core::cast::transmute;
|
||||
use core::result;
|
||||
use core::uint;
|
||||
use std::cast::transmute;
|
||||
use std::result;
|
||||
use std::uint;
|
||||
|
||||
/**
|
||||
* Convert a str to `ip_addr`
|
||||
|
|
@ -205,7 +203,7 @@ pub mod v4 {
|
|||
}).collect();
|
||||
if parts.len() != 4 {
|
||||
Err(fmt!("'%s' doesn't have 4 parts", ip))
|
||||
} else if parts.contains(&256) {
|
||||
} else if parts.iter().any_(|x| *x == 256u) {
|
||||
Err(fmt!("invalid octal in addr '%s'", ip))
|
||||
} else {
|
||||
Ok(Ipv4Rep {
|
||||
|
|
@ -248,13 +246,12 @@ pub mod v4 {
|
|||
}
|
||||
}
|
||||
pub mod v6 {
|
||||
use core::prelude::*;
|
||||
|
||||
use net::ip::{IpAddr, Ipv6, ParseAddrErr};
|
||||
use uv_ip6_addr = uv::ll::ip6_addr;
|
||||
use uv_ip6_name = uv::ll::ip6_name;
|
||||
|
||||
use core::result;
|
||||
use std::result;
|
||||
|
||||
/**
|
||||
* Convert a str to `ip_addr`
|
||||
|
|
@ -371,7 +368,7 @@ mod test {
|
|||
use net_ip::v6;
|
||||
use uv;
|
||||
|
||||
use core::result;
|
||||
use std::result;
|
||||
|
||||
#[test]
|
||||
fn test_ip_ipv4_parse_and_format_ip() {
|
||||
|
|
@ -426,7 +423,7 @@ mod test {
|
|||
let results = result::unwrap(ga_result);
|
||||
debug!("test_get_addr: Number of results for %s: %?",
|
||||
localhost_name, results.len());
|
||||
for results.each |r| {
|
||||
for results.iter().advance |r| {
|
||||
let ipv_prefix = match *r {
|
||||
Ipv4(_) => ~"IPv4",
|
||||
Ipv6(_) => ~"IPv6"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use future;
|
||||
use future_spawn = future::spawn;
|
||||
|
|
@ -22,18 +21,18 @@ use uv;
|
|||
use uv::iotask;
|
||||
use uv::iotask::IoTask;
|
||||
|
||||
use core::io;
|
||||
use core::libc::size_t;
|
||||
use core::libc;
|
||||
use core::comm::{stream, Port, SharedChan};
|
||||
use core::ptr;
|
||||
use core::result::{Result};
|
||||
use core::result;
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use std::io;
|
||||
use std::libc::size_t;
|
||||
use std::libc;
|
||||
use std::comm::{stream, Port, SharedChan};
|
||||
use std::ptr;
|
||||
use std::result::{Result};
|
||||
use std::result;
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
|
||||
pub mod rustrt {
|
||||
use core::libc;
|
||||
use std::libc;
|
||||
|
||||
#[nolink]
|
||||
pub extern {
|
||||
|
|
@ -57,7 +56,7 @@ pub struct TcpSocket {
|
|||
|
||||
#[unsafe_destructor]
|
||||
impl Drop for TcpSocket {
|
||||
fn finalize(&self) {
|
||||
fn drop(&self) {
|
||||
tear_down_socket_data(self.socket_data)
|
||||
}
|
||||
}
|
||||
|
|
@ -360,7 +359,7 @@ pub fn write_future(sock: &TcpSocket, raw_write_data: ~[u8])
|
|||
* # Returns
|
||||
*
|
||||
* * A `Result` instance that will either contain a
|
||||
* `core::comm::Port<Result<~[u8], TcpErrData>>` that the user can read
|
||||
* `std::comm::Port<Result<~[u8], TcpErrData>>` that the user can read
|
||||
* (and * optionally, loop on) from until `read_stop` is called, or a
|
||||
* `TcpErrData` record
|
||||
*/
|
||||
|
|
@ -619,7 +618,7 @@ pub fn accept(new_conn: TcpNewConnection)
|
|||
* callback's arguments are:
|
||||
* * `new_conn` - an opaque type that can be passed to
|
||||
* `net::tcp::accept` in order to be converted to a `TcpSocket`.
|
||||
* * `kill_ch` - channel of type `core::comm::Chan<Option<tcp_err_data>>`.
|
||||
* * `kill_ch` - channel of type `std::comm::Chan<Option<tcp_err_data>>`.
|
||||
* this channel can be used to send a message to cause `listen` to begin
|
||||
* closing the underlying libuv data structures.
|
||||
*
|
||||
|
|
@ -683,7 +682,7 @@ fn listen_common(host_ip: ip::IpAddr,
|
|||
// will defeat a move sigil, as is done to the host_ip
|
||||
// arg above.. this same pattern works w/o complaint in
|
||||
// tcp::connect (because the iotask::interact cb isn't
|
||||
// nested within a core::comm::listen block)
|
||||
// nested within a std::comm::listen block)
|
||||
let loc_ip = copy(host_ip);
|
||||
do iotask::interact(iotask) |loop_ptr| {
|
||||
unsafe {
|
||||
|
|
@ -976,9 +975,7 @@ impl io::Writer for TcpSocketBuf {
|
|||
let socket_data_ptr: *TcpSocketData =
|
||||
&(*((*(self.data)).sock).socket_data);
|
||||
let w_result = write_common_impl(socket_data_ptr,
|
||||
vec::slice(data,
|
||||
0,
|
||||
data.len()).to_vec());
|
||||
data.slice(0, data.len()).to_owned());
|
||||
if w_result.is_err() {
|
||||
let err_data = w_result.get_err();
|
||||
debug!(
|
||||
|
|
@ -1431,7 +1428,6 @@ struct TcpBufferedSocketData {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use core::prelude::*;
|
||||
|
||||
use net::ip;
|
||||
use net::tcp::{GenericListenErr, TcpConnectErrData, TcpListenErrData};
|
||||
|
|
@ -1440,12 +1436,12 @@ mod test {
|
|||
use uv::iotask::IoTask;
|
||||
use uv;
|
||||
|
||||
use core::cell::Cell;
|
||||
use core::comm::{stream, SharedChan};
|
||||
use core::io;
|
||||
use core::result;
|
||||
use core::str;
|
||||
use core::task;
|
||||
use std::cell::Cell;
|
||||
use std::comm::{stream, SharedChan};
|
||||
use std::io;
|
||||
use std::result;
|
||||
use std::str;
|
||||
use std::task;
|
||||
|
||||
// FIXME don't run on fbsd or linux 32 bit (#2064)
|
||||
#[cfg(target_os="win32")]
|
||||
|
|
@ -1459,33 +1455,23 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_gl_tcp_server_and_client_ipv4() {
|
||||
unsafe {
|
||||
impl_gl_tcp_ipv4_server_and_client();
|
||||
}
|
||||
impl_gl_tcp_ipv4_server_and_client();
|
||||
}
|
||||
#[test]
|
||||
fn test_gl_tcp_get_peer_addr() {
|
||||
unsafe {
|
||||
impl_gl_tcp_ipv4_get_peer_addr();
|
||||
}
|
||||
impl_gl_tcp_ipv4_get_peer_addr();
|
||||
}
|
||||
#[test]
|
||||
fn test_gl_tcp_ipv4_client_error_connection_refused() {
|
||||
unsafe {
|
||||
impl_gl_tcp_ipv4_client_error_connection_refused();
|
||||
}
|
||||
impl_gl_tcp_ipv4_client_error_connection_refused();
|
||||
}
|
||||
#[test]
|
||||
fn test_gl_tcp_server_address_in_use() {
|
||||
unsafe {
|
||||
impl_gl_tcp_ipv4_server_address_in_use();
|
||||
}
|
||||
impl_gl_tcp_ipv4_server_address_in_use();
|
||||
}
|
||||
#[test]
|
||||
fn test_gl_tcp_server_access_denied() {
|
||||
unsafe {
|
||||
impl_gl_tcp_ipv4_server_access_denied();
|
||||
}
|
||||
impl_gl_tcp_ipv4_server_access_denied();
|
||||
}
|
||||
// Strange failure on Windows. --pcwalton
|
||||
#[test]
|
||||
|
|
@ -1757,7 +1743,7 @@ mod test {
|
|||
}
|
||||
|
||||
pub fn impl_tcp_socket_impl_reader_handles_eof() {
|
||||
use core::io::{Reader,ReaderUtil};
|
||||
use std::io::{Reader,ReaderUtil};
|
||||
|
||||
let hl_loop = &uv::global_loop::get();
|
||||
let server_ip = "127.0.0.1";
|
||||
|
|
|
|||
|
|
@ -12,14 +12,13 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::cmp::Eq;
|
||||
use core::io::{Reader, ReaderUtil};
|
||||
use core::io;
|
||||
use core::hashmap::HashMap;
|
||||
use core::to_bytes;
|
||||
use core::uint;
|
||||
use std::cmp::Eq;
|
||||
use std::io::{Reader, ReaderUtil};
|
||||
use std::io;
|
||||
use std::hashmap::HashMap;
|
||||
use std::to_bytes;
|
||||
use std::uint;
|
||||
|
||||
#[deriving(Clone, Eq)]
|
||||
struct Url {
|
||||
|
|
@ -93,10 +92,10 @@ fn encode_inner(s: &str, full_url: bool) -> ~str {
|
|||
out.push_char(ch);
|
||||
}
|
||||
|
||||
_ => out += fmt!("%%%X", ch as uint)
|
||||
_ => out.push_str(fmt!("%%%X", ch as uint))
|
||||
}
|
||||
} else {
|
||||
out += fmt!("%%%X", ch as uint);
|
||||
out.push_str(fmt!("%%%X", ch as uint));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -192,7 +191,7 @@ fn encode_plus(s: &str) -> ~str {
|
|||
out.push_char(ch);
|
||||
}
|
||||
' ' => out.push_char('+'),
|
||||
_ => out += fmt!("%%%X", ch as uint)
|
||||
_ => out.push_str(fmt!("%%%X", ch as uint))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -207,10 +206,10 @@ pub fn encode_form_urlencoded(m: &HashMap<~str, ~[~str]>) -> ~str {
|
|||
let mut out = ~"";
|
||||
let mut first = true;
|
||||
|
||||
for m.each |key, values| {
|
||||
for m.iter().advance |(key, values)| {
|
||||
let key = encode_plus(*key);
|
||||
|
||||
for values.each |value| {
|
||||
for values.iter().advance |value| {
|
||||
if first {
|
||||
first = false;
|
||||
} else {
|
||||
|
|
@ -218,7 +217,7 @@ pub fn encode_form_urlencoded(m: &HashMap<~str, ~[~str]>) -> ~str {
|
|||
first = false;
|
||||
}
|
||||
|
||||
out += fmt!("%s=%s", key, encode_plus(*value));
|
||||
out.push_str(fmt!("%s=%s", key, encode_plus(*value)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -342,7 +341,7 @@ fn query_from_str(rawquery: &str) -> Query {
|
|||
|
||||
pub fn query_to_str(query: &Query) -> ~str {
|
||||
let mut strvec = ~[];
|
||||
for query.each |kv| {
|
||||
for query.iter().advance |kv| {
|
||||
match kv {
|
||||
&(ref k, ref v) => {
|
||||
strvec.push(fmt!("%s=%s",
|
||||
|
|
@ -415,7 +414,9 @@ fn get_authority(rawurl: &str) ->
|
|||
let mut port = None;
|
||||
|
||||
let mut colon_count = 0;
|
||||
let mut (pos, begin, end) = (0, 2, len);
|
||||
let mut pos = 0;
|
||||
let mut begin = 2;
|
||||
let mut end = len;
|
||||
|
||||
for rawurl.iter().enumerate().advance |(i,c)| {
|
||||
if i < 2 { loop; } // ignore the leading //
|
||||
|
|
@ -519,8 +520,9 @@ fn get_authority(rawurl: &str) ->
|
|||
let end = end; // make end immutable so it can be captured
|
||||
|
||||
let host_is_end_plus_one: &fn() -> bool = || {
|
||||
let xs = ['?', '#', '/'];
|
||||
end+1 == len
|
||||
&& !['?', '#', '/'].contains(&(rawurl[end] as char))
|
||||
&& !xs.iter().any_(|x| *x == (rawurl[end] as char))
|
||||
};
|
||||
|
||||
// finish up
|
||||
|
|
@ -800,7 +802,7 @@ mod tests {
|
|||
|
||||
use net_url::*;
|
||||
|
||||
use core::hashmap::HashMap;
|
||||
use std::hashmap::HashMap;
|
||||
|
||||
#[test]
|
||||
fn test_url_parse() {
|
||||
|
|
|
|||
|
|
@ -18,13 +18,12 @@ A BigInt is a combination of BigUint and Sign.
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
use core::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
|
||||
use core::int;
|
||||
use core::num::{IntConvertible, Zero, One, ToStrRadix, FromStrRadix, Orderable};
|
||||
use core::str;
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use std::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
|
||||
use std::int;
|
||||
use std::num::{IntConvertible, Zero, One, ToStrRadix, FromStrRadix, Orderable};
|
||||
use std::str;
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
|
||||
/**
|
||||
A BigDigit is a BigUint's composing element.
|
||||
|
|
@ -284,13 +283,13 @@ impl Mul<BigUint, BigUint> for BigUint {
|
|||
if n == 1 { return copy *a; }
|
||||
|
||||
let mut carry = 0;
|
||||
let prod = do vec::map(a.data) |ai| {
|
||||
let prod = do a.data.iter().transform |ai| {
|
||||
let (hi, lo) = BigDigit::from_uint(
|
||||
(*ai as uint) * (n as uint) + (carry as uint)
|
||||
);
|
||||
carry = hi;
|
||||
lo
|
||||
};
|
||||
}.collect::<~[BigDigit]>();
|
||||
if carry == 0 { return BigUint::new(prod) };
|
||||
return BigUint::new(prod + [carry]);
|
||||
}
|
||||
|
|
@ -298,9 +297,8 @@ impl Mul<BigUint, BigUint> for BigUint {
|
|||
|
||||
fn cut_at(a: &BigUint, n: uint) -> (BigUint, BigUint) {
|
||||
let mid = uint::min(a.data.len(), n);
|
||||
return (BigUint::from_slice(vec::slice(a.data, mid,
|
||||
a.data.len())),
|
||||
BigUint::from_slice(vec::slice(a.data, 0, mid)));
|
||||
return (BigUint::from_slice(a.data.slice(mid, a.data.len())),
|
||||
BigUint::from_slice(a.data.slice(0, mid)));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -381,7 +379,8 @@ impl Integer for BigUint {
|
|||
let mut d = Zero::zero::<BigUint>();
|
||||
let mut n = 1;
|
||||
while m >= b {
|
||||
let mut (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
|
||||
let (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
|
||||
let mut d0 = d0;
|
||||
let mut prod = b * d0;
|
||||
while prod > m {
|
||||
// FIXME(#6050): overloaded operators force moves with generic types
|
||||
|
|
@ -413,7 +412,7 @@ impl Integer for BigUint {
|
|||
return (Zero::zero(), Zero::zero(), copy *a);
|
||||
}
|
||||
|
||||
let an = vec::slice(a.data, a.data.len() - n, a.data.len());
|
||||
let an = a.data.slice(a.data.len() - n, a.data.len());
|
||||
let bn = *b.data.last();
|
||||
let mut d = ~[];
|
||||
let mut carry = 0;
|
||||
|
|
@ -443,7 +442,8 @@ impl Integer for BigUint {
|
|||
|
||||
fn gcd(&self, other: &BigUint) -> BigUint {
|
||||
// Use Euclid's algorithm
|
||||
let mut (m, n) = (copy *self, copy *other);
|
||||
let mut m = copy *self;
|
||||
let mut n = copy *other;
|
||||
while !m.is_zero() {
|
||||
let temp = m;
|
||||
m = n % temp;
|
||||
|
|
@ -507,11 +507,11 @@ impl ToStrRadix for BigUint {
|
|||
let mut m = n;
|
||||
while m > divider {
|
||||
let (d, m0) = m.div_mod_floor(÷r);
|
||||
result += [m0.to_uint() as BigDigit];
|
||||
result.push(m0.to_uint() as BigDigit);
|
||||
m = d;
|
||||
}
|
||||
if !m.is_zero() {
|
||||
result += [m.to_uint() as BigDigit];
|
||||
result.push(m.to_uint() as BigDigit);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -578,7 +578,7 @@ impl BigUint {
|
|||
let mut power: BigUint = One::one();
|
||||
loop {
|
||||
let start = uint::max(end, unit_len) - unit_len;
|
||||
match uint::parse_bytes(vec::slice(buf, start, end), radix) {
|
||||
match uint::parse_bytes(buf.slice(start, end), radix) {
|
||||
// FIXME(#6102): Assignment operator for BigInt causes ICE
|
||||
// Some(d) => n += BigUint::from_uint(d) * power,
|
||||
Some(d) => n = n + BigUint::from_uint(d) * power,
|
||||
|
|
@ -618,13 +618,13 @@ impl BigUint {
|
|||
if n_bits == 0 || self.is_zero() { return copy *self; }
|
||||
|
||||
let mut carry = 0;
|
||||
let shifted = do vec::map(self.data) |elem| {
|
||||
let shifted = do self.data.iter().transform |elem| {
|
||||
let (hi, lo) = BigDigit::from_uint(
|
||||
(*elem as uint) << n_bits | (carry as uint)
|
||||
);
|
||||
carry = hi;
|
||||
lo
|
||||
};
|
||||
}.collect::<~[BigDigit]>();
|
||||
if carry == 0 { return BigUint::new(shifted); }
|
||||
return BigUint::new(shifted + [carry]);
|
||||
}
|
||||
|
|
@ -634,7 +634,7 @@ impl BigUint {
|
|||
if n_unit == 0 { return copy *self; }
|
||||
if self.data.len() < n_unit { return Zero::zero(); }
|
||||
return BigUint::from_slice(
|
||||
vec::slice(self.data, n_unit, self.data.len())
|
||||
self.data.slice(n_unit, self.data.len())
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -1132,7 +1132,7 @@ impl BigInt {
|
|||
sign = Minus;
|
||||
start = 1;
|
||||
}
|
||||
return BigUint::parse_bytes(vec::slice(buf, start, buf.len()), radix)
|
||||
return BigUint::parse_bytes(buf.slice(start, buf.len()), radix)
|
||||
.map_consume(|bu| BigInt::from_biguint(sign, bu));
|
||||
}
|
||||
|
||||
|
|
@ -1147,16 +1147,15 @@ impl BigInt {
|
|||
|
||||
#[cfg(test)]
|
||||
mod biguint_tests {
|
||||
use core::prelude::*;
|
||||
|
||||
use super::*;
|
||||
|
||||
use core::cmp::{Less, Equal, Greater};
|
||||
use core::int;
|
||||
use core::num::{IntConvertible, Zero, One, FromStrRadix};
|
||||
use core::str;
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use std::cmp::{Less, Equal, Greater};
|
||||
use std::int;
|
||||
use std::num::{IntConvertible, Zero, One, FromStrRadix};
|
||||
use std::str;
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
|
||||
#[test]
|
||||
fn test_from_slice() {
|
||||
|
|
@ -1173,10 +1172,10 @@ mod biguint_tests {
|
|||
|
||||
#[test]
|
||||
fn test_cmp() {
|
||||
let data = [ &[], &[1], &[2], &[-1], &[0, 1], &[2, 1], &[1, 1, 1] ]
|
||||
let data: ~[BigUint] = [ &[], &[1], &[2], &[-1], &[0, 1], &[2, 1], &[1, 1, 1] ]
|
||||
.map(|v| BigUint::from_slice(*v));
|
||||
for data.eachi |i, ni| {
|
||||
for vec::slice(data, i, data.len()).eachi |j0, nj| {
|
||||
for data.iter().enumerate().advance |(i, ni)| {
|
||||
for data.slice(i, data.len()).iter().enumerate().advance |(j0, nj)| {
|
||||
let j = j0 + i;
|
||||
if i == j {
|
||||
assert_eq!(ni.cmp(nj), Equal);
|
||||
|
|
@ -1349,7 +1348,7 @@ mod biguint_tests {
|
|||
|
||||
#[test]
|
||||
fn test_add() {
|
||||
for sum_triples.each |elm| {
|
||||
for sum_triples.iter().advance |elm| {
|
||||
let (aVec, bVec, cVec) = *elm;
|
||||
let a = BigUint::from_slice(aVec);
|
||||
let b = BigUint::from_slice(bVec);
|
||||
|
|
@ -1362,7 +1361,7 @@ mod biguint_tests {
|
|||
|
||||
#[test]
|
||||
fn test_sub() {
|
||||
for sum_triples.each |elm| {
|
||||
for sum_triples.iter().advance |elm| {
|
||||
let (aVec, bVec, cVec) = *elm;
|
||||
let a = BigUint::from_slice(aVec);
|
||||
let b = BigUint::from_slice(bVec);
|
||||
|
|
@ -1413,7 +1412,7 @@ mod biguint_tests {
|
|||
|
||||
#[test]
|
||||
fn test_mul() {
|
||||
for mul_triples.each |elm| {
|
||||
for mul_triples.iter().advance |elm| {
|
||||
let (aVec, bVec, cVec) = *elm;
|
||||
let a = BigUint::from_slice(aVec);
|
||||
let b = BigUint::from_slice(bVec);
|
||||
|
|
@ -1423,7 +1422,7 @@ mod biguint_tests {
|
|||
assert!(b * a == c);
|
||||
}
|
||||
|
||||
for div_rem_quadruples.each |elm| {
|
||||
for div_rem_quadruples.iter().advance |elm| {
|
||||
let (aVec, bVec, cVec, dVec) = *elm;
|
||||
let a = BigUint::from_slice(aVec);
|
||||
let b = BigUint::from_slice(bVec);
|
||||
|
|
@ -1437,7 +1436,7 @@ mod biguint_tests {
|
|||
|
||||
#[test]
|
||||
fn test_div_rem() {
|
||||
for mul_triples.each |elm| {
|
||||
for mul_triples.iter().advance |elm| {
|
||||
let (aVec, bVec, cVec) = *elm;
|
||||
let a = BigUint::from_slice(aVec);
|
||||
let b = BigUint::from_slice(bVec);
|
||||
|
|
@ -1451,7 +1450,7 @@ mod biguint_tests {
|
|||
}
|
||||
}
|
||||
|
||||
for div_rem_quadruples.each |elm| {
|
||||
for div_rem_quadruples.iter().advance |elm| {
|
||||
let (aVec, bVec, cVec, dVec) = *elm;
|
||||
let a = BigUint::from_slice(aVec);
|
||||
let b = BigUint::from_slice(bVec);
|
||||
|
|
@ -1567,9 +1566,10 @@ mod biguint_tests {
|
|||
|
||||
#[test]
|
||||
fn test_to_str_radix() {
|
||||
for to_str_pairs().each |num_pair| {
|
||||
let r = to_str_pairs();
|
||||
for r.iter().advance |num_pair| {
|
||||
let &(n, rs) = num_pair;
|
||||
for rs.each |str_pair| {
|
||||
for rs.iter().advance |str_pair| {
|
||||
let &(radix, str) = str_pair;
|
||||
assert_eq!(n.to_str_radix(radix), str);
|
||||
}
|
||||
|
|
@ -1578,9 +1578,10 @@ mod biguint_tests {
|
|||
|
||||
#[test]
|
||||
fn test_from_str_radix() {
|
||||
for to_str_pairs().each |num_pair| {
|
||||
let r = to_str_pairs();
|
||||
for r.iter().advance |num_pair| {
|
||||
let &(n, rs) = num_pair;
|
||||
for rs.each |str_pair| {
|
||||
for rs.iter().advance |str_pair| {
|
||||
let &(radix, str) = str_pair;
|
||||
assert_eq!(&n, &FromStrRadix::from_str_radix(str, radix).get());
|
||||
}
|
||||
|
|
@ -1620,15 +1621,14 @@ mod biguint_tests {
|
|||
|
||||
#[cfg(test)]
|
||||
mod bigint_tests {
|
||||
use core::prelude::*;
|
||||
|
||||
use super::*;
|
||||
|
||||
use core::cmp::{Less, Equal, Greater};
|
||||
use core::int;
|
||||
use core::num::{IntConvertible, Zero, One, FromStrRadix};
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use std::cmp::{Less, Equal, Greater};
|
||||
use std::int;
|
||||
use std::num::{IntConvertible, Zero, One, FromStrRadix};
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
|
||||
#[test]
|
||||
fn test_from_biguint() {
|
||||
|
|
@ -1651,8 +1651,8 @@ mod bigint_tests {
|
|||
nums.push(Zero::zero());
|
||||
nums.push_all_move(vs.map(|s| BigInt::from_slice(Plus, *s)));
|
||||
|
||||
for nums.eachi |i, ni| {
|
||||
for vec::slice(nums, i, nums.len()).eachi |j0, nj| {
|
||||
for nums.iter().enumerate().advance |(i, ni)| {
|
||||
for nums.slice(i, nums.len()).iter().enumerate().advance |(j0, nj)| {
|
||||
let j = i + j0;
|
||||
if i == j {
|
||||
assert_eq!(ni.cmp(nj), Equal);
|
||||
|
|
@ -1756,7 +1756,7 @@ mod bigint_tests {
|
|||
|
||||
#[test]
|
||||
fn test_add() {
|
||||
for sum_triples.each |elm| {
|
||||
for sum_triples.iter().advance |elm| {
|
||||
let (aVec, bVec, cVec) = *elm;
|
||||
let a = BigInt::from_slice(Plus, aVec);
|
||||
let b = BigInt::from_slice(Plus, bVec);
|
||||
|
|
@ -1775,7 +1775,7 @@ mod bigint_tests {
|
|||
|
||||
#[test]
|
||||
fn test_sub() {
|
||||
for sum_triples.each |elm| {
|
||||
for sum_triples.iter().advance |elm| {
|
||||
let (aVec, bVec, cVec) = *elm;
|
||||
let a = BigInt::from_slice(Plus, aVec);
|
||||
let b = BigInt::from_slice(Plus, bVec);
|
||||
|
|
@ -1832,7 +1832,7 @@ mod bigint_tests {
|
|||
|
||||
#[test]
|
||||
fn test_mul() {
|
||||
for mul_triples.each |elm| {
|
||||
for mul_triples.iter().advance |elm| {
|
||||
let (aVec, bVec, cVec) = *elm;
|
||||
let a = BigInt::from_slice(Plus, aVec);
|
||||
let b = BigInt::from_slice(Plus, bVec);
|
||||
|
|
@ -1845,7 +1845,7 @@ mod bigint_tests {
|
|||
assert!((-b) * a == -c);
|
||||
}
|
||||
|
||||
for div_rem_quadruples.each |elm| {
|
||||
for div_rem_quadruples.iter().advance |elm| {
|
||||
let (aVec, bVec, cVec, dVec) = *elm;
|
||||
let a = BigInt::from_slice(Plus, aVec);
|
||||
let b = BigInt::from_slice(Plus, bVec);
|
||||
|
|
@ -1884,7 +1884,7 @@ mod bigint_tests {
|
|||
}
|
||||
}
|
||||
|
||||
for mul_triples.each |elm| {
|
||||
for mul_triples.iter().advance |elm| {
|
||||
let (aVec, bVec, cVec) = *elm;
|
||||
let a = BigInt::from_slice(Plus, aVec);
|
||||
let b = BigInt::from_slice(Plus, bVec);
|
||||
|
|
@ -1894,7 +1894,7 @@ mod bigint_tests {
|
|||
if !b.is_zero() { check(&c, &b, &a, &Zero::zero()); }
|
||||
}
|
||||
|
||||
for div_rem_quadruples.each |elm| {
|
||||
for div_rem_quadruples.iter().advance |elm| {
|
||||
let (aVec, bVec, cVec, dVec) = *elm;
|
||||
let a = BigInt::from_slice(Plus, aVec);
|
||||
let b = BigInt::from_slice(Plus, bVec);
|
||||
|
|
@ -1927,7 +1927,7 @@ mod bigint_tests {
|
|||
check_sub(&a.neg(), b, &q.neg(), &r.neg());
|
||||
check_sub(&a.neg(), &b.neg(), q, &r.neg());
|
||||
}
|
||||
for mul_triples.each |elm| {
|
||||
for mul_triples.iter().advance |elm| {
|
||||
let (aVec, bVec, cVec) = *elm;
|
||||
let a = BigInt::from_slice(Plus, aVec);
|
||||
let b = BigInt::from_slice(Plus, bVec);
|
||||
|
|
@ -1937,7 +1937,7 @@ mod bigint_tests {
|
|||
if !b.is_zero() { check(&c, &b, &a, &Zero::zero()); }
|
||||
}
|
||||
|
||||
for div_rem_quadruples.each |elm| {
|
||||
for div_rem_quadruples.iter().advance |elm| {
|
||||
let (aVec, bVec, cVec, dVec) = *elm;
|
||||
let a = BigInt::from_slice(Plus, aVec);
|
||||
let b = BigInt::from_slice(Plus, bVec);
|
||||
|
|
|
|||
|
|
@ -11,9 +11,8 @@
|
|||
|
||||
//! Complex numbers.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::num::{Zero,One,ToStrRadix};
|
||||
use std::num::{Zero,One,ToStrRadix};
|
||||
|
||||
// FIXME #1284: handle complex NaN & infinity etc. This
|
||||
// probably doesn't map to C's _Complex correctly.
|
||||
|
|
@ -193,7 +192,7 @@ impl<T: ToStrRadix + Num + Ord> ToStrRadix for Cmplx<T> {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use core::num::{Zero,One,Real};
|
||||
use std::num::{Zero,One,Real};
|
||||
|
||||
pub static _0_0i : Complex = Cmplx { re: 0f, im: 0f };
|
||||
pub static _1_0i : Complex = Cmplx { re: 1f, im: 0f };
|
||||
|
|
@ -238,14 +237,14 @@ mod test {
|
|||
fn test_scale_unscale() {
|
||||
assert_eq!(_05_05i.scale(2f), _1_1i);
|
||||
assert_eq!(_1_1i.unscale(2f), _05_05i);
|
||||
for all_consts.each |&c| {
|
||||
for all_consts.iter().advance |&c| {
|
||||
assert_eq!(c.scale(2f).unscale(2f), c);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_conj() {
|
||||
for all_consts.each |&c| {
|
||||
for all_consts.iter().advance |&c| {
|
||||
assert_eq!(c.conj(), Cmplx::new(c.re, -c.im));
|
||||
assert_eq!(c.conj().conj(), c);
|
||||
}
|
||||
|
|
@ -282,12 +281,12 @@ mod test {
|
|||
let (r, theta) = c.to_polar();
|
||||
assert!((c - Cmplx::from_polar(&r, &theta)).norm() < 1e-6);
|
||||
}
|
||||
for all_consts.each |&c| { test(c); }
|
||||
for all_consts.iter().advance |&c| { test(c); }
|
||||
}
|
||||
|
||||
mod arith {
|
||||
use super::*;
|
||||
use core::num::Zero;
|
||||
use std::num::Zero;
|
||||
|
||||
#[test]
|
||||
fn test_add() {
|
||||
|
|
@ -295,7 +294,7 @@ mod test {
|
|||
assert_eq!(_0_1i + _1_0i, _1_1i);
|
||||
assert_eq!(_1_0i + _neg1_1i, _0_1i);
|
||||
|
||||
for all_consts.each |&c| {
|
||||
for all_consts.iter().advance |&c| {
|
||||
assert_eq!(_0_0i + c, c);
|
||||
assert_eq!(c + _0_0i, c);
|
||||
}
|
||||
|
|
@ -307,7 +306,7 @@ mod test {
|
|||
assert_eq!(_0_1i - _1_0i, _neg1_1i);
|
||||
assert_eq!(_0_1i - _neg1_1i, _1_0i);
|
||||
|
||||
for all_consts.each |&c| {
|
||||
for all_consts.iter().advance |&c| {
|
||||
assert_eq!(c - _0_0i, c);
|
||||
assert_eq!(c - c, _0_0i);
|
||||
}
|
||||
|
|
@ -322,7 +321,7 @@ mod test {
|
|||
assert_eq!(_0_1i * _0_1i, -_1_0i);
|
||||
assert_eq!(_0_1i * _0_1i * _0_1i * _0_1i, _1_0i);
|
||||
|
||||
for all_consts.each |&c| {
|
||||
for all_consts.iter().advance |&c| {
|
||||
assert_eq!(c * _1_0i, c);
|
||||
assert_eq!(_1_0i * c, c);
|
||||
}
|
||||
|
|
@ -330,7 +329,7 @@ mod test {
|
|||
#[test]
|
||||
fn test_div() {
|
||||
assert_eq!(_neg1_1i / _0_1i, _1_1i);
|
||||
for all_consts.each |&c| {
|
||||
for all_consts.iter().advance |&c| {
|
||||
if c != Zero::zero() {
|
||||
assert_eq!(c / c, _1_0i);
|
||||
}
|
||||
|
|
@ -340,7 +339,7 @@ mod test {
|
|||
fn test_neg() {
|
||||
assert_eq!(-_1_0i + _0_1i, _neg1_1i);
|
||||
assert_eq!((-_0_1i) * _0_1i, _1_0i);
|
||||
for all_consts.each |&c| {
|
||||
for all_consts.iter().advance |&c| {
|
||||
assert_eq!(-(-c), c);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,11 +10,10 @@
|
|||
|
||||
//! Rational numbers
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::cmp;
|
||||
use core::from_str::FromStr;
|
||||
use core::num::{Zero,One,ToStrRadix,FromStrRadix,Round};
|
||||
use std::cmp;
|
||||
use std::from_str::FromStr;
|
||||
use std::num::{Zero,One,ToStrRadix,FromStrRadix,Round};
|
||||
use super::bigint::BigInt;
|
||||
|
||||
/// Represents the ratio between 2 numbers.
|
||||
|
|
@ -277,11 +276,10 @@ impl<T: FromStrRadix + Clone + Integer + Ord>
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use core::prelude::*;
|
||||
|
||||
use super::*;
|
||||
use core::num::{Zero,One,FromStrRadix,IntConvertible};
|
||||
use core::from_str::FromStr;
|
||||
use std::num::{Zero,One,FromStrRadix,IntConvertible};
|
||||
use std::from_str::FromStr;
|
||||
|
||||
pub static _0 : Rational = Ratio { numer: 0, denom: 1};
|
||||
pub static _1 : Rational = Ratio { numer: 1, denom: 1};
|
||||
|
|
@ -482,7 +480,8 @@ mod test {
|
|||
assert_eq!(FromStr::from_str::<Rational>(s), None);
|
||||
}
|
||||
|
||||
for ["0 /1", "abc", "", "1/", "--1/2","3/2/1"].each |&s| {
|
||||
let xs = ["0 /1", "abc", "", "1/", "--1/2","3/2/1"];
|
||||
for xs.iter().advance |&s| {
|
||||
test(s);
|
||||
}
|
||||
}
|
||||
|
|
@ -521,7 +520,8 @@ mod test {
|
|||
assert_eq!(FromStrRadix::from_str_radix::<Rational>(s, 3), None);
|
||||
}
|
||||
|
||||
for ["0 /1", "abc", "", "1/", "--1/2","3/2/1", "3/2"].each |&s| {
|
||||
let xs = ["0 /1", "abc", "", "1/", "--1/2","3/2/1", "3/2"];
|
||||
for xs.iter().advance |&s| {
|
||||
test(s);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,13 +8,12 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::cast;
|
||||
use core::ptr;
|
||||
use core::sys;
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use std::cast;
|
||||
use std::ptr;
|
||||
use std::sys;
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
use future_spawn = future::spawn;
|
||||
|
||||
/**
|
||||
|
|
@ -33,7 +32,7 @@ static min_granularity : uint = 1024u;
|
|||
* This is used to build most of the other parallel vector functions,
|
||||
* like map or alli.
|
||||
*/
|
||||
fn map_slices<A:Copy + Owned,B:Copy + Owned>(
|
||||
fn map_slices<A:Copy + Send,B:Copy + Send>(
|
||||
xs: &[A],
|
||||
f: &fn() -> ~fn(uint, v: &[A]) -> B)
|
||||
-> ~[B] {
|
||||
|
|
@ -88,26 +87,26 @@ fn map_slices<A:Copy + Owned,B:Copy + Owned>(
|
|||
}
|
||||
|
||||
/// A parallel version of map.
|
||||
pub fn map<A:Copy + Owned,B:Copy + Owned>(
|
||||
pub fn map<A:Copy + Send,B:Copy + Send>(
|
||||
xs: &[A], fn_factory: &fn() -> ~fn(&A) -> B) -> ~[B] {
|
||||
vec::concat(map_slices(xs, || {
|
||||
let f = fn_factory();
|
||||
let result: ~fn(uint, &[A]) -> ~[B] =
|
||||
|_, slice| vec::map(slice, |x| f(x));
|
||||
|_, slice| slice.iter().transform(|x| f(x)).collect();
|
||||
result
|
||||
}))
|
||||
}
|
||||
|
||||
/// A parallel version of mapi.
|
||||
pub fn mapi<A:Copy + Owned,B:Copy + Owned>(
|
||||
pub fn mapi<A:Copy + Send,B:Copy + Send>(
|
||||
xs: &[A],
|
||||
fn_factory: &fn() -> ~fn(uint, &A) -> B) -> ~[B] {
|
||||
let slices = map_slices(xs, || {
|
||||
let f = fn_factory();
|
||||
let result: ~fn(uint, &[A]) -> ~[B] = |base, slice| {
|
||||
vec::mapi(slice, |i, x| {
|
||||
slice.iter().enumerate().transform(|(i, x)| {
|
||||
f(i + base, x)
|
||||
})
|
||||
}).collect()
|
||||
};
|
||||
result
|
||||
});
|
||||
|
|
@ -118,7 +117,7 @@ pub fn mapi<A:Copy + Owned,B:Copy + Owned>(
|
|||
}
|
||||
|
||||
/// Returns true if the function holds for all elements in the vector.
|
||||
pub fn alli<A:Copy + Owned>(
|
||||
pub fn alli<A:Copy + Send>(
|
||||
xs: &[A],
|
||||
fn_factory: &fn() -> ~fn(uint, &A) -> bool) -> bool
|
||||
{
|
||||
|
|
@ -133,7 +132,7 @@ pub fn alli<A:Copy + Owned>(
|
|||
}
|
||||
|
||||
/// Returns true if the function holds for any elements in the vector.
|
||||
pub fn any<A:Copy + Owned>(
|
||||
pub fn any<A:Copy + Send>(
|
||||
xs: &[A],
|
||||
fn_factory: &fn() -> ~fn(&A) -> bool) -> bool {
|
||||
let mapped = map_slices(xs, || {
|
||||
|
|
|
|||
|
|
@ -12,27 +12,16 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::old_iter::BaseIter;
|
||||
use core::unstable::intrinsics::{move_val_init, init};
|
||||
use core::util::{replace, swap};
|
||||
use core::vec;
|
||||
use std::unstable::intrinsics::{move_val_init, init};
|
||||
use std::util::{replace, swap};
|
||||
use std::vec;
|
||||
|
||||
#[allow(missing_doc)]
|
||||
/// A priority queue implemented with a binary heap
|
||||
pub struct PriorityQueue<T> {
|
||||
priv data: ~[T],
|
||||
}
|
||||
|
||||
impl<T:Ord> BaseIter<T> for PriorityQueue<T> {
|
||||
/// Visit all values in the underlying vector.
|
||||
///
|
||||
/// The values are **not** visited in order.
|
||||
fn each(&self, f: &fn(&T) -> bool) -> bool { self.data.each(f) }
|
||||
|
||||
fn size_hint(&self) -> Option<uint> { self.data.size_hint() }
|
||||
}
|
||||
|
||||
impl<T:Ord> Container for PriorityQueue<T> {
|
||||
/// Returns the length of the queue
|
||||
fn len(&self) -> uint { self.data.len() }
|
||||
|
|
@ -47,6 +36,12 @@ impl<T:Ord> Mutable for PriorityQueue<T> {
|
|||
}
|
||||
|
||||
impl<T:Ord> PriorityQueue<T> {
|
||||
/// An iterator visiting all values in underlying vector, in
|
||||
/// arbitrary order.
|
||||
pub fn iter<'a>(&'a self) -> PriorityQueueIterator<'a, T> {
|
||||
PriorityQueueIterator { iter: self.data.iter() }
|
||||
}
|
||||
|
||||
/// Returns the greatest item in the queue - fails if empty
|
||||
pub fn top<'a>(&'a self) -> &'a T { &self.data[0] }
|
||||
|
||||
|
|
@ -56,12 +51,12 @@ impl<T:Ord> PriorityQueue<T> {
|
|||
}
|
||||
|
||||
/// Returns the number of elements the queue can hold without reallocating
|
||||
pub fn capacity(&self) -> uint { vec::capacity(&self.data) }
|
||||
pub fn capacity(&self) -> uint { self.data.capacity() }
|
||||
|
||||
pub fn reserve(&mut self, n: uint) { vec::reserve(&mut self.data, n) }
|
||||
pub fn reserve(&mut self, n: uint) { self.data.reserve(n) }
|
||||
|
||||
pub fn reserve_at_least(&mut self, n: uint) {
|
||||
vec::reserve_at_least(&mut self.data, n)
|
||||
self.data.reserve_at_least(n)
|
||||
}
|
||||
|
||||
/// Pop the greatest item from the queue - fails if empty
|
||||
|
|
@ -112,7 +107,7 @@ impl<T:Ord> PriorityQueue<T> {
|
|||
let mut end = q.len();
|
||||
while end > 1 {
|
||||
end -= 1;
|
||||
vec::swap(q.data, 0, end);
|
||||
q.data.swap(0, end);
|
||||
q.siftdown_range(0, end)
|
||||
}
|
||||
q.to_vec()
|
||||
|
|
@ -183,11 +178,33 @@ impl<T:Ord> PriorityQueue<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// PriorityQueue iterator
|
||||
pub struct PriorityQueueIterator <'self, T> {
|
||||
priv iter: vec::VecIterator<'self, T>,
|
||||
}
|
||||
|
||||
impl<'self, T> Iterator<&'self T> for PriorityQueueIterator<'self, T> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<(&'self T)> { self.iter.next() }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use sort::merge_sort;
|
||||
use priority_queue::PriorityQueue;
|
||||
|
||||
#[test]
|
||||
fn test_iterator() {
|
||||
let data = ~[5, 9, 3];
|
||||
let iterout = ~[9, 5, 3];
|
||||
let pq = PriorityQueue::from_vec(data);
|
||||
let mut i = 0;
|
||||
for pq.iter().advance |el| {
|
||||
assert_eq!(*el, iterout[i]);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_top_and_pop() {
|
||||
let data = ~[2u, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
|
||||
|
|
|
|||
|
|
@ -13,21 +13,20 @@
|
|||
/** Task-local reference counted smart pointers
|
||||
|
||||
Task-local reference counted smart pointers are an alternative to managed boxes with deterministic
|
||||
destruction. They are restricted to containing types that are either `Owned` or `Const` (or both) to
|
||||
destruction. They are restricted to containing types that are either `Send` or `Freeze` (or both) to
|
||||
prevent cycles.
|
||||
|
||||
Neither `Rc<T>` or `RcMut<T>` is ever `Owned` and `RcMut<T>` is never `Const`. If `T` is `Const`, a
|
||||
Neither `Rc<T>` or `RcMut<T>` is ever `Send` and `RcMut<T>` is never `Freeze`. If `T` is `Freeze`, a
|
||||
cycle cannot be created with `Rc<T>` because there is no way to modify it after creation.
|
||||
|
||||
*/
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::cast;
|
||||
use core::libc::{c_void, size_t, malloc, free};
|
||||
use core::ptr;
|
||||
use core::sys;
|
||||
use core::unstable::intrinsics;
|
||||
use std::cast;
|
||||
use std::libc::{c_void, size_t, malloc, free};
|
||||
use std::ptr;
|
||||
use std::sys;
|
||||
use std::unstable::intrinsics;
|
||||
|
||||
struct RcBox<T> {
|
||||
value: T,
|
||||
|
|
@ -35,7 +34,8 @@ struct RcBox<T> {
|
|||
}
|
||||
|
||||
/// Immutable reference counted pointer type
|
||||
#[non_owned]
|
||||
#[unsafe_no_drop_flag]
|
||||
#[no_send]
|
||||
pub struct Rc<T> {
|
||||
priv ptr: *mut RcBox<T>,
|
||||
}
|
||||
|
|
@ -50,12 +50,12 @@ impl<T> Rc<T> {
|
|||
}
|
||||
|
||||
// FIXME: #6516: should be a static method
|
||||
pub fn rc_from_owned<T: Owned>(value: T) -> Rc<T> {
|
||||
pub fn rc_from_owned<T: Send>(value: T) -> Rc<T> {
|
||||
unsafe { Rc::new(value) }
|
||||
}
|
||||
|
||||
// FIXME: #6516: should be a static method
|
||||
pub fn rc_from_const<T: Const>(value: T) -> Rc<T> {
|
||||
pub fn rc_from_const<T: Freeze>(value: T) -> Rc<T> {
|
||||
unsafe { Rc::new(value) }
|
||||
}
|
||||
|
||||
|
|
@ -68,12 +68,14 @@ impl<T> Rc<T> {
|
|||
|
||||
#[unsafe_destructor]
|
||||
impl<T> Drop for Rc<T> {
|
||||
fn finalize(&self) {
|
||||
fn drop(&self) {
|
||||
unsafe {
|
||||
(*self.ptr).count -= 1;
|
||||
if (*self.ptr).count == 0 {
|
||||
ptr::replace_ptr(self.ptr, intrinsics::uninit());
|
||||
free(self.ptr as *c_void)
|
||||
if self.ptr.is_not_null() {
|
||||
(*self.ptr).count -= 1;
|
||||
if (*self.ptr).count == 0 {
|
||||
ptr::replace_ptr(self.ptr, intrinsics::uninit());
|
||||
free(self.ptr as *c_void)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -101,7 +103,7 @@ impl<T: DeepClone> DeepClone for Rc<T> {
|
|||
#[cfg(test)]
|
||||
mod test_rc {
|
||||
use super::*;
|
||||
use core::cell::Cell;
|
||||
use std::cell::Cell;
|
||||
|
||||
#[test]
|
||||
fn test_clone() {
|
||||
|
|
@ -165,7 +167,10 @@ struct RcMutBox<T> {
|
|||
|
||||
/// Mutable reference counted pointer type
|
||||
#[non_owned]
|
||||
#[mutable]
|
||||
#[no_send]
|
||||
#[mutable] // XXX remove after snap
|
||||
#[no_freeze]
|
||||
#[unsafe_no_drop_flag]
|
||||
pub struct RcMut<T> {
|
||||
priv ptr: *mut RcMutBox<T>,
|
||||
}
|
||||
|
|
@ -180,12 +185,12 @@ impl<T> RcMut<T> {
|
|||
}
|
||||
|
||||
// FIXME: #6516: should be a static method
|
||||
pub fn rc_mut_from_owned<T: Owned>(value: T) -> RcMut<T> {
|
||||
pub fn rc_mut_from_owned<T: Send>(value: T) -> RcMut<T> {
|
||||
unsafe { RcMut::new(value) }
|
||||
}
|
||||
|
||||
// FIXME: #6516: should be a static method
|
||||
pub fn rc_mut_from_const<T: Const>(value: T) -> RcMut<T> {
|
||||
pub fn rc_mut_from_const<T: Freeze>(value: T) -> RcMut<T> {
|
||||
unsafe { RcMut::new(value) }
|
||||
}
|
||||
|
||||
|
|
@ -218,12 +223,14 @@ impl<T> RcMut<T> {
|
|||
|
||||
#[unsafe_destructor]
|
||||
impl<T> Drop for RcMut<T> {
|
||||
fn finalize(&self) {
|
||||
fn drop(&self) {
|
||||
unsafe {
|
||||
(*self.ptr).count -= 1;
|
||||
if (*self.ptr).count == 0 {
|
||||
ptr::replace_ptr(self.ptr, uninit());
|
||||
free(self.ptr as *c_void)
|
||||
if self.ptr.is_not_null() {
|
||||
(*self.ptr).count -= 1;
|
||||
if (*self.ptr).count == 0 {
|
||||
ptr::replace_ptr(self.ptr, uninit());
|
||||
free(self.ptr as *c_void)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,14 +11,13 @@
|
|||
// FIXME #3921. This is unsafe because linenoise uses global mutable
|
||||
// state without mutexes.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::libc::{c_char, c_int};
|
||||
use core::local_data;
|
||||
use core::str;
|
||||
use std::libc::{c_char, c_int};
|
||||
use std::local_data;
|
||||
use std::str;
|
||||
|
||||
pub mod rustrt {
|
||||
use core::libc::{c_char, c_int};
|
||||
use std::libc::{c_char, c_int};
|
||||
|
||||
pub extern {
|
||||
pub unsafe fn linenoise(prompt: *c_char) -> *c_char;
|
||||
|
|
|
|||
|
|
@ -35,11 +35,10 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use core::str;
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
use std::str;
|
||||
|
||||
/// The type of ropes.
|
||||
pub type Rope = node::Root;
|
||||
|
|
@ -447,7 +446,6 @@ pub fn loop_leaves(rope: Rope, it: &fn(node::Leaf) -> bool) -> bool{
|
|||
|
||||
pub mod iterator {
|
||||
pub mod leaf {
|
||||
use core::prelude::*;
|
||||
|
||||
use rope::{Rope, node};
|
||||
|
||||
|
|
@ -462,7 +460,6 @@ pub mod iterator {
|
|||
}
|
||||
}
|
||||
pub mod char {
|
||||
use core::prelude::*;
|
||||
|
||||
use rope::{Rope, node};
|
||||
|
||||
|
|
@ -558,13 +555,12 @@ pub fn char_at(rope: Rope, pos: uint) -> char {
|
|||
Section: Implementation
|
||||
*/
|
||||
pub mod node {
|
||||
use core::prelude::*;
|
||||
|
||||
use rope::node;
|
||||
|
||||
use core::cast;
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use std::cast;
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
|
||||
/// Implementation of type `rope`
|
||||
pub enum Root {
|
||||
|
|
@ -1078,7 +1074,7 @@ pub mod node {
|
|||
|
||||
pub fn loop_chars(node: @Node, it: &fn(c: char) -> bool) -> bool {
|
||||
return loop_leaves(node,|leaf| {
|
||||
leaf.content.slice(leaf.byte_offset, leaf.byte_len).iter().all(it)
|
||||
leaf.content.slice(leaf.byte_offset, leaf.byte_len).iter().all(|c| it(c))
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1101,7 +1097,7 @@ pub mod node {
|
|||
loop {
|
||||
match (*current) {
|
||||
Leaf(x) => return it(x),
|
||||
Concat(ref x) => if loop_leaves(x.left, it) { //non tail call
|
||||
Concat(ref x) => if loop_leaves(x.left, |l| it(l)) { //non tail call
|
||||
current = x.right; //tail call
|
||||
} else {
|
||||
return false;
|
||||
|
|
@ -1141,11 +1137,10 @@ pub mod node {
|
|||
}
|
||||
|
||||
pub mod leaf_iterator {
|
||||
use core::prelude::*;
|
||||
|
||||
use rope::node::{Concat, Leaf, Node, height};
|
||||
|
||||
use core::vec;
|
||||
use std::vec;
|
||||
|
||||
pub struct T {
|
||||
stack: ~[@Node],
|
||||
|
|
@ -1184,7 +1179,6 @@ pub mod node {
|
|||
}
|
||||
|
||||
pub mod char_iterator {
|
||||
use core::prelude::*;
|
||||
|
||||
use rope::node::{Leaf, Node};
|
||||
use rope::node::leaf_iterator;
|
||||
|
|
@ -1267,12 +1261,11 @@ pub mod node {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use core::prelude::*;
|
||||
|
||||
use rope::*;
|
||||
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
|
||||
//Utility function, used for sanity check
|
||||
fn rope_to_string(r: Rope) -> ~str {
|
||||
|
|
|
|||
|
|
@ -12,15 +12,14 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::char;
|
||||
use core::cmp;
|
||||
use core::io::{ReaderUtil};
|
||||
use core::io;
|
||||
use core::option::{Option, Some, None};
|
||||
use core::to_str::ToStr;
|
||||
use core::uint;
|
||||
use std::char;
|
||||
use std::cmp;
|
||||
use std::io::{ReaderUtil};
|
||||
use std::io;
|
||||
use std::option::{Option, Some, None};
|
||||
use std::to_str::ToStr;
|
||||
use std::uint;
|
||||
|
||||
#[deriving(Eq)]
|
||||
pub enum Identifier {
|
||||
|
|
@ -79,12 +78,12 @@ impl ToStr for Version {
|
|||
let s = if self.pre.is_empty() {
|
||||
s
|
||||
} else {
|
||||
s + "-" + self.pre.map(|i| i.to_str()).connect(".")
|
||||
fmt!("%s-%s", s, self.pre.map(|i| i.to_str()).connect("."))
|
||||
};
|
||||
if self.build.is_empty() {
|
||||
s
|
||||
} else {
|
||||
s + "+" + self.build.map(|i| i.to_str()).connect(".")
|
||||
fmt!("%s+%s", s, self.build.map(|i| i.to_str()).connect("."))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,13 +17,12 @@ Core encoding and decoding interfaces.
|
|||
#[allow(missing_doc)];
|
||||
#[forbid(non_camel_case_types)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::at_vec;
|
||||
use core::hashmap::{HashMap, HashSet};
|
||||
use core::trie::{TrieMap, TrieSet};
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use std::at_vec;
|
||||
use std::hashmap::{HashMap, HashSet};
|
||||
use std::trie::{TrieMap, TrieSet};
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
use deque::Deque;
|
||||
use dlist::DList;
|
||||
use treemap::{TreeMap, TreeSet};
|
||||
|
|
@ -432,7 +431,7 @@ impl<D:Decoder,T:Decodable<D>> Decodable<D> for @T {
|
|||
impl<'self, S:Encoder,T:Encodable<S>> Encodable<S> for &'self [T] {
|
||||
fn encode(&self, s: &mut S) {
|
||||
do s.emit_seq(self.len()) |s| {
|
||||
for self.eachi |i, e| {
|
||||
for self.iter().enumerate().advance |(i, e)| {
|
||||
s.emit_seq_elt(i, |s| e.encode(s))
|
||||
}
|
||||
}
|
||||
|
|
@ -442,7 +441,7 @@ impl<'self, S:Encoder,T:Encodable<S>> Encodable<S> for &'self [T] {
|
|||
impl<S:Encoder,T:Encodable<S>> Encodable<S> for ~[T] {
|
||||
fn encode(&self, s: &mut S) {
|
||||
do s.emit_seq(self.len()) |s| {
|
||||
for self.eachi |i, e| {
|
||||
for self.iter().enumerate().advance |(i, e)| {
|
||||
s.emit_seq_elt(i, |s| e.encode(s))
|
||||
}
|
||||
}
|
||||
|
|
@ -462,7 +461,7 @@ impl<D:Decoder,T:Decodable<D>> Decodable<D> for ~[T] {
|
|||
impl<S:Encoder,T:Encodable<S>> Encodable<S> for @[T] {
|
||||
fn encode(&self, s: &mut S) {
|
||||
do s.emit_seq(self.len()) |s| {
|
||||
for self.eachi |i, e| {
|
||||
for self.iter().enumerate().advance |(i, e)| {
|
||||
s.emit_seq_elt(i, |s| e.encode(s))
|
||||
}
|
||||
}
|
||||
|
|
@ -710,7 +709,7 @@ impl<
|
|||
fn encode(&self, e: &mut E) {
|
||||
do e.emit_map(self.len()) |e| {
|
||||
let mut i = 0;
|
||||
for self.each |key, val| {
|
||||
for self.iter().advance |(key, val)| {
|
||||
e.emit_map_elt_key(i, |e| key.encode(e));
|
||||
e.emit_map_elt_val(i, |e| val.encode(e));
|
||||
i += 1;
|
||||
|
|
@ -744,7 +743,7 @@ impl<
|
|||
fn encode(&self, s: &mut S) {
|
||||
do s.emit_seq(self.len()) |s| {
|
||||
let mut i = 0;
|
||||
for self.each |e| {
|
||||
for self.iter().advance |e| {
|
||||
s.emit_seq_elt(i, |s| e.encode(s));
|
||||
i += 1;
|
||||
}
|
||||
|
|
@ -832,7 +831,7 @@ impl<
|
|||
fn encode(&self, e: &mut E) {
|
||||
do e.emit_map(self.len()) |e| {
|
||||
let mut i = 0;
|
||||
for self.each |key, val| {
|
||||
for self.iter().advance |(key, val)| {
|
||||
e.emit_map_elt_key(i, |e| key.encode(e));
|
||||
e.emit_map_elt_val(i, |e| val.encode(e));
|
||||
i += 1;
|
||||
|
|
@ -866,7 +865,7 @@ impl<
|
|||
fn encode(&self, s: &mut S) {
|
||||
do s.emit_seq(self.len()) |s| {
|
||||
let mut i = 0;
|
||||
for self.each |e| {
|
||||
for self.iter().advance |e| {
|
||||
s.emit_seq_elt(i, |s| e.encode(s));
|
||||
i += 1;
|
||||
}
|
||||
|
|
@ -901,7 +900,7 @@ pub trait EncoderHelpers {
|
|||
impl<S:Encoder> EncoderHelpers for S {
|
||||
fn emit_from_vec<T>(&mut self, v: &[T], f: &fn(&mut S, &T)) {
|
||||
do self.emit_seq(v.len()) |this| {
|
||||
for v.eachi |i, e| {
|
||||
for v.iter().enumerate().advance |(i, e)| {
|
||||
do this.emit_seq_elt(i) |this| {
|
||||
f(this, e)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,410 +0,0 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/*!
|
||||
* An implementation of the SHA-1 cryptographic hash.
|
||||
*
|
||||
* First create a `sha1` object using the `sha1` constructor, then
|
||||
* feed it input using the `input` or `input_str` methods, which may be
|
||||
* called any number of times.
|
||||
*
|
||||
* After the entire input has been fed to the hash read the result using
|
||||
* the `result` or `result_str` methods.
|
||||
*
|
||||
* The `sha1` object may be reused to create multiple hashes by calling
|
||||
* the `reset` method.
|
||||
*/
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
|
||||
/*
|
||||
* A SHA-1 implementation derived from Paul E. Jones's reference
|
||||
* implementation, which is written for clarity, not speed. At some
|
||||
* point this will want to be rewritten.
|
||||
*/
|
||||
|
||||
/// The SHA-1 interface
|
||||
trait Sha1 {
|
||||
/// Provide message input as bytes
|
||||
fn input(&mut self, &const [u8]);
|
||||
/// Provide message input as string
|
||||
fn input_str(&mut self, &str);
|
||||
/**
|
||||
* Read the digest as a vector of 20 bytes. After calling this no further
|
||||
* input may be provided until reset is called.
|
||||
*/
|
||||
fn result(&mut self) -> ~[u8];
|
||||
/**
|
||||
* Read the digest as a hex string. After calling this no further
|
||||
* input may be provided until reset is called.
|
||||
*/
|
||||
fn result_str(&mut self) -> ~str;
|
||||
/// Reset the SHA-1 state for reuse
|
||||
fn reset(&mut self);
|
||||
}
|
||||
|
||||
// Some unexported constants
|
||||
static digest_buf_len: uint = 5u;
|
||||
static msg_block_len: uint = 64u;
|
||||
static work_buf_len: uint = 80u;
|
||||
static k0: u32 = 0x5A827999u32;
|
||||
static k1: u32 = 0x6ED9EBA1u32;
|
||||
static k2: u32 = 0x8F1BBCDCu32;
|
||||
static k3: u32 = 0xCA62C1D6u32;
|
||||
|
||||
|
||||
/// Construct a `sha` object
|
||||
pub fn sha1() -> @Sha1 {
|
||||
struct Sha1State
|
||||
{ h: ~[u32],
|
||||
len_low: u32,
|
||||
len_high: u32,
|
||||
msg_block: ~[u8],
|
||||
msg_block_idx: uint,
|
||||
computed: bool,
|
||||
work_buf: @mut ~[u32]};
|
||||
|
||||
fn add_input(st: &mut Sha1State, msg: &const [u8]) {
|
||||
assert!((!st.computed));
|
||||
for vec::each_const(msg) |element| {
|
||||
st.msg_block[st.msg_block_idx] = *element;
|
||||
st.msg_block_idx += 1u;
|
||||
st.len_low += 8u32;
|
||||
if st.len_low == 0u32 {
|
||||
st.len_high += 1u32;
|
||||
if st.len_high == 0u32 {
|
||||
// FIXME: Need better failure mode (#2346)
|
||||
fail!();
|
||||
}
|
||||
}
|
||||
if st.msg_block_idx == msg_block_len { process_msg_block(st); }
|
||||
}
|
||||
}
|
||||
fn process_msg_block(st: &mut Sha1State) {
|
||||
assert_eq!(st.h.len(), digest_buf_len);
|
||||
assert_eq!(st.work_buf.len(), work_buf_len);
|
||||
let mut t: int; // Loop counter
|
||||
let w = st.work_buf;
|
||||
|
||||
// Initialize the first 16 words of the vector w
|
||||
t = 0;
|
||||
while t < 16 {
|
||||
let mut tmp;
|
||||
tmp = (st.msg_block[t * 4] as u32) << 24u32;
|
||||
tmp = tmp | (st.msg_block[t * 4 + 1] as u32) << 16u32;
|
||||
tmp = tmp | (st.msg_block[t * 4 + 2] as u32) << 8u32;
|
||||
tmp = tmp | (st.msg_block[t * 4 + 3] as u32);
|
||||
w[t] = tmp;
|
||||
t += 1;
|
||||
}
|
||||
|
||||
// Initialize the rest of vector w
|
||||
while t < 80 {
|
||||
let val = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16];
|
||||
w[t] = circular_shift(1u32, val);
|
||||
t += 1;
|
||||
}
|
||||
let mut a = st.h[0];
|
||||
let mut b = st.h[1];
|
||||
let mut c = st.h[2];
|
||||
let mut d = st.h[3];
|
||||
let mut e = st.h[4];
|
||||
let mut temp: u32;
|
||||
t = 0;
|
||||
while t < 20 {
|
||||
temp = circular_shift(5u32, a) + (b & c | !b & d) + e + w[t] + k0;
|
||||
e = d;
|
||||
d = c;
|
||||
c = circular_shift(30u32, b);
|
||||
b = a;
|
||||
a = temp;
|
||||
t += 1;
|
||||
}
|
||||
while t < 40 {
|
||||
temp = circular_shift(5u32, a) + (b ^ c ^ d) + e + w[t] + k1;
|
||||
e = d;
|
||||
d = c;
|
||||
c = circular_shift(30u32, b);
|
||||
b = a;
|
||||
a = temp;
|
||||
t += 1;
|
||||
}
|
||||
while t < 60 {
|
||||
temp =
|
||||
circular_shift(5u32, a) + (b & c | b & d | c & d) + e + w[t] +
|
||||
k2;
|
||||
e = d;
|
||||
d = c;
|
||||
c = circular_shift(30u32, b);
|
||||
b = a;
|
||||
a = temp;
|
||||
t += 1;
|
||||
}
|
||||
while t < 80 {
|
||||
temp = circular_shift(5u32, a) + (b ^ c ^ d) + e + w[t] + k3;
|
||||
e = d;
|
||||
d = c;
|
||||
c = circular_shift(30u32, b);
|
||||
b = a;
|
||||
a = temp;
|
||||
t += 1;
|
||||
}
|
||||
st.h[0] = st.h[0] + a;
|
||||
st.h[1] = st.h[1] + b;
|
||||
st.h[2] = st.h[2] + c;
|
||||
st.h[3] = st.h[3] + d;
|
||||
st.h[4] = st.h[4] + e;
|
||||
st.msg_block_idx = 0u;
|
||||
}
|
||||
fn circular_shift(bits: u32, word: u32) -> u32 {
|
||||
return word << bits | word >> 32u32 - bits;
|
||||
}
|
||||
fn mk_result(st: &mut Sha1State) -> ~[u8] {
|
||||
if !(*st).computed { pad_msg(st); (*st).computed = true; }
|
||||
let mut rs: ~[u8] = ~[];
|
||||
for st.h.mut_iter().advance |ptr_hpart| {
|
||||
let hpart = *ptr_hpart;
|
||||
let a = (hpart >> 24u32 & 0xFFu32) as u8;
|
||||
let b = (hpart >> 16u32 & 0xFFu32) as u8;
|
||||
let c = (hpart >> 8u32 & 0xFFu32) as u8;
|
||||
let d = (hpart & 0xFFu32) as u8;
|
||||
rs = vec::append(copy rs, [a, b, c, d]);
|
||||
}
|
||||
return rs;
|
||||
}
|
||||
|
||||
/*
|
||||
* According to the standard, the message must be padded to an even
|
||||
* 512 bits. The first padding bit must be a '1'. The last 64 bits
|
||||
* represent the length of the original message. All bits in between
|
||||
* should be 0. This function will pad the message according to those
|
||||
* rules by filling the msg_block vector accordingly. It will also
|
||||
* call process_msg_block() appropriately. When it returns, it
|
||||
* can be assumed that the message digest has been computed.
|
||||
*/
|
||||
fn pad_msg(st: &mut Sha1State) {
|
||||
assert_eq!((*st).msg_block.len(), msg_block_len);
|
||||
|
||||
/*
|
||||
* Check to see if the current message block is too small to hold
|
||||
* the initial padding bits and length. If so, we will pad the
|
||||
* block, process it, and then continue padding into a second block.
|
||||
*/
|
||||
if (*st).msg_block_idx > 55u {
|
||||
(*st).msg_block[(*st).msg_block_idx] = 0x80u8;
|
||||
(*st).msg_block_idx += 1u;
|
||||
while (*st).msg_block_idx < msg_block_len {
|
||||
(*st).msg_block[(*st).msg_block_idx] = 0u8;
|
||||
(*st).msg_block_idx += 1u;
|
||||
}
|
||||
process_msg_block(st);
|
||||
} else {
|
||||
(*st).msg_block[(*st).msg_block_idx] = 0x80u8;
|
||||
(*st).msg_block_idx += 1u;
|
||||
}
|
||||
while (*st).msg_block_idx < 56u {
|
||||
(*st).msg_block[(*st).msg_block_idx] = 0u8;
|
||||
(*st).msg_block_idx += 1u;
|
||||
}
|
||||
|
||||
// Store the message length as the last 8 octets
|
||||
(*st).msg_block[56] = ((*st).len_high >> 24u32 & 0xFFu32) as u8;
|
||||
(*st).msg_block[57] = ((*st).len_high >> 16u32 & 0xFFu32) as u8;
|
||||
(*st).msg_block[58] = ((*st).len_high >> 8u32 & 0xFFu32) as u8;
|
||||
(*st).msg_block[59] = ((*st).len_high & 0xFFu32) as u8;
|
||||
(*st).msg_block[60] = ((*st).len_low >> 24u32 & 0xFFu32) as u8;
|
||||
(*st).msg_block[61] = ((*st).len_low >> 16u32 & 0xFFu32) as u8;
|
||||
(*st).msg_block[62] = ((*st).len_low >> 8u32 & 0xFFu32) as u8;
|
||||
(*st).msg_block[63] = ((*st).len_low & 0xFFu32) as u8;
|
||||
process_msg_block(st);
|
||||
}
|
||||
|
||||
impl Sha1 for Sha1State {
|
||||
fn reset(&mut self) {
|
||||
assert_eq!(self.h.len(), digest_buf_len);
|
||||
self.len_low = 0u32;
|
||||
self.len_high = 0u32;
|
||||
self.msg_block_idx = 0u;
|
||||
self.h[0] = 0x67452301u32;
|
||||
self.h[1] = 0xEFCDAB89u32;
|
||||
self.h[2] = 0x98BADCFEu32;
|
||||
self.h[3] = 0x10325476u32;
|
||||
self.h[4] = 0xC3D2E1F0u32;
|
||||
self.computed = false;
|
||||
}
|
||||
fn input(&mut self, msg: &const [u8]) { add_input(self, msg); }
|
||||
fn input_str(&mut self, msg: &str) {
|
||||
add_input(self, msg.as_bytes());
|
||||
}
|
||||
fn result(&mut self) -> ~[u8] { return mk_result(self); }
|
||||
fn result_str(&mut self) -> ~str {
|
||||
let rr = mk_result(self);
|
||||
let mut s = ~"";
|
||||
for rr.each |b| {
|
||||
let hex = uint::to_str_radix(*b as uint, 16u);
|
||||
if hex.len() == 1 {
|
||||
s += "0";
|
||||
}
|
||||
s += hex;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
let st = Sha1State {
|
||||
h: vec::from_elem(digest_buf_len, 0u32),
|
||||
len_low: 0u32,
|
||||
len_high: 0u32,
|
||||
msg_block: vec::from_elem(msg_block_len, 0u8),
|
||||
msg_block_idx: 0u,
|
||||
computed: false,
|
||||
work_buf: @mut vec::from_elem(work_buf_len, 0u32)
|
||||
};
|
||||
let mut sh = @st as @Sha1;
|
||||
sh.reset();
|
||||
return sh;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use sha1;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
struct Test {
|
||||
input: ~str,
|
||||
output: ~[u8],
|
||||
output_str: ~str,
|
||||
}
|
||||
|
||||
fn a_million_letter_a() -> ~str {
|
||||
let mut i = 0;
|
||||
let mut rs = ~"";
|
||||
while i < 100000 {
|
||||
rs.push_str("aaaaaaaaaa");
|
||||
i += 1;
|
||||
}
|
||||
return rs;
|
||||
}
|
||||
// Test messages from FIPS 180-1
|
||||
|
||||
let fips_180_1_tests = ~[
|
||||
Test {
|
||||
input: ~"abc",
|
||||
output: ~[
|
||||
0xA9u8, 0x99u8, 0x3Eu8, 0x36u8,
|
||||
0x47u8, 0x06u8, 0x81u8, 0x6Au8,
|
||||
0xBAu8, 0x3Eu8, 0x25u8, 0x71u8,
|
||||
0x78u8, 0x50u8, 0xC2u8, 0x6Cu8,
|
||||
0x9Cu8, 0xD0u8, 0xD8u8, 0x9Du8,
|
||||
],
|
||||
output_str: ~"a9993e364706816aba3e25717850c26c9cd0d89d"
|
||||
},
|
||||
Test {
|
||||
input:
|
||||
~"abcdbcdecdefdefgefghfghighij" +
|
||||
"hijkijkljklmklmnlmnomnopnopq",
|
||||
output: ~[
|
||||
0x84u8, 0x98u8, 0x3Eu8, 0x44u8,
|
||||
0x1Cu8, 0x3Bu8, 0xD2u8, 0x6Eu8,
|
||||
0xBAu8, 0xAEu8, 0x4Au8, 0xA1u8,
|
||||
0xF9u8, 0x51u8, 0x29u8, 0xE5u8,
|
||||
0xE5u8, 0x46u8, 0x70u8, 0xF1u8,
|
||||
],
|
||||
output_str: ~"84983e441c3bd26ebaae4aa1f95129e5e54670f1"
|
||||
},
|
||||
Test {
|
||||
input: a_million_letter_a(),
|
||||
output: ~[
|
||||
0x34u8, 0xAAu8, 0x97u8, 0x3Cu8,
|
||||
0xD4u8, 0xC4u8, 0xDAu8, 0xA4u8,
|
||||
0xF6u8, 0x1Eu8, 0xEBu8, 0x2Bu8,
|
||||
0xDBu8, 0xADu8, 0x27u8, 0x31u8,
|
||||
0x65u8, 0x34u8, 0x01u8, 0x6Fu8,
|
||||
],
|
||||
output_str: ~"34aa973cd4c4daa4f61eeb2bdbad27316534016f"
|
||||
},
|
||||
];
|
||||
// Examples from wikipedia
|
||||
|
||||
let wikipedia_tests = ~[
|
||||
Test {
|
||||
input: ~"The quick brown fox jumps over the lazy dog",
|
||||
output: ~[
|
||||
0x2fu8, 0xd4u8, 0xe1u8, 0xc6u8,
|
||||
0x7au8, 0x2du8, 0x28u8, 0xfcu8,
|
||||
0xedu8, 0x84u8, 0x9eu8, 0xe1u8,
|
||||
0xbbu8, 0x76u8, 0xe7u8, 0x39u8,
|
||||
0x1bu8, 0x93u8, 0xebu8, 0x12u8,
|
||||
],
|
||||
output_str: ~"2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
|
||||
},
|
||||
Test {
|
||||
input: ~"The quick brown fox jumps over the lazy cog",
|
||||
output: ~[
|
||||
0xdeu8, 0x9fu8, 0x2cu8, 0x7fu8,
|
||||
0xd2u8, 0x5eu8, 0x1bu8, 0x3au8,
|
||||
0xfau8, 0xd3u8, 0xe8u8, 0x5au8,
|
||||
0x0bu8, 0xd1u8, 0x7du8, 0x9bu8,
|
||||
0x10u8, 0x0du8, 0xb4u8, 0xb3u8,
|
||||
],
|
||||
output_str: ~"de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3",
|
||||
},
|
||||
];
|
||||
let tests = fips_180_1_tests + wikipedia_tests;
|
||||
fn check_vec_eq(v0: ~[u8], v1: ~[u8]) {
|
||||
assert_eq!(v0.len(), v1.len());
|
||||
let len = v0.len();
|
||||
let mut i = 0u;
|
||||
while i < len {
|
||||
let a = v0[i];
|
||||
let b = v1[i];
|
||||
assert_eq!(a, b);
|
||||
i += 1u;
|
||||
}
|
||||
}
|
||||
// Test that it works when accepting the message all at once
|
||||
|
||||
let mut sh = sha1::sha1();
|
||||
for tests.each |t| {
|
||||
sh.input_str(t.input);
|
||||
let out = sh.result();
|
||||
check_vec_eq(copy t.output, out);
|
||||
|
||||
let out_str = sh.result_str();
|
||||
assert_eq!(out_str.len(), 40);
|
||||
assert!(out_str == t.output_str);
|
||||
|
||||
sh.reset();
|
||||
}
|
||||
|
||||
|
||||
// Test that it works when accepting the message in pieces
|
||||
for tests.each |t| {
|
||||
let len = t.input.len();
|
||||
let mut left = len;
|
||||
while left > 0u {
|
||||
let take = (left + 1u) / 2u;
|
||||
sh.input_str(t.input.slice(len - left, take + len - left));
|
||||
left = left - take;
|
||||
}
|
||||
let out = sh.result();
|
||||
check_vec_eq(copy t.output, out);
|
||||
|
||||
let out_str = sh.result_str();
|
||||
assert_eq!(out_str.len(), 40);
|
||||
assert!(out_str == t.output_str);
|
||||
|
||||
sh.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,15 +15,11 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::cmp;
|
||||
use core::container::{Container, Mutable, Map, Set};
|
||||
use core::old_iter::BaseIter;
|
||||
use core::old_iter;
|
||||
use core::uint;
|
||||
use core::util::replace;
|
||||
use core::vec;
|
||||
use std::cmp;
|
||||
use std::container::{Container, Mutable, Map, Set};
|
||||
use std::uint;
|
||||
use std::util::replace;
|
||||
|
||||
#[allow(missing_doc)]
|
||||
pub struct SmallIntMap<T> {
|
||||
|
|
@ -58,38 +54,6 @@ impl<V> Map<uint, V> for SmallIntMap<V> {
|
|||
self.find(key).is_some()
|
||||
}
|
||||
|
||||
/// Visit all key-value pairs in order
|
||||
fn each<'a>(&'a self, it: &fn(&uint, &'a V) -> bool) -> bool {
|
||||
for uint::range(0, self.v.len()) |i| {
|
||||
match self.v[i] {
|
||||
Some(ref elt) => if !it(&i, elt) { return false; },
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Visit all keys in order
|
||||
fn each_key(&self, blk: &fn(key: &uint) -> bool) -> bool {
|
||||
self.each(|k, _| blk(k))
|
||||
}
|
||||
|
||||
/// Visit all values in order
|
||||
fn each_value<'a>(&'a self, blk: &fn(value: &'a V) -> bool) -> bool {
|
||||
self.each(|_, v| blk(v))
|
||||
}
|
||||
|
||||
/// Iterate over the map and mutate the contained values
|
||||
fn mutate_values(&mut self, it: &fn(&uint, &mut V) -> bool) -> bool {
|
||||
for uint::range(0, self.v.len()) |i| {
|
||||
match self.v[i] {
|
||||
Some(ref mut elt) => if !it(&i, elt) { return false; },
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Return a reference to the value corresponding to the key
|
||||
fn find<'a>(&'a self, key: &uint) -> Option<&'a V> {
|
||||
if *key < self.v.len() {
|
||||
|
|
@ -121,7 +85,7 @@ impl<V> Map<uint, V> for SmallIntMap<V> {
|
|||
let exists = self.contains_key(&key);
|
||||
let len = self.v.len();
|
||||
if len <= key {
|
||||
vec::grow_fn(&mut self.v, key - len + 1, |_| None);
|
||||
self.v.grow_fn(key - len + 1, |_| None);
|
||||
}
|
||||
self.v[key] = Some(value);
|
||||
!exists
|
||||
|
|
@ -158,6 +122,38 @@ impl<V> SmallIntMap<V> {
|
|||
/// Create an empty SmallIntMap
|
||||
pub fn new() -> SmallIntMap<V> { SmallIntMap{v: ~[]} }
|
||||
|
||||
/// Visit all key-value pairs in order
|
||||
pub fn each<'a>(&'a self, it: &fn(&uint, &'a V) -> bool) -> bool {
|
||||
for uint::range(0, self.v.len()) |i| {
|
||||
match self.v[i] {
|
||||
Some(ref elt) => if !it(&i, elt) { return false; },
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Visit all keys in order
|
||||
pub fn each_key(&self, blk: &fn(key: &uint) -> bool) -> bool {
|
||||
self.each(|k, _| blk(k))
|
||||
}
|
||||
|
||||
/// Visit all values in order
|
||||
pub fn each_value<'a>(&'a self, blk: &fn(value: &'a V) -> bool) -> bool {
|
||||
self.each(|_, v| blk(v))
|
||||
}
|
||||
|
||||
/// Iterate over the map and mutate the contained values
|
||||
pub fn mutate_values(&mut self, it: &fn(&uint, &mut V) -> bool) -> bool {
|
||||
for uint::range(0, self.v.len()) |i| {
|
||||
match self.v[i] {
|
||||
Some(ref mut elt) => if !it(&i, elt) { return false; },
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Visit all key-value pairs in reverse order
|
||||
pub fn each_reverse<'a>(&'a self, it: &fn(uint, &'a V) -> bool) -> bool {
|
||||
for uint::range_rev(self.v.len(), 0) |i| {
|
||||
|
|
@ -212,12 +208,6 @@ impl Mutable for SmallIntSet {
|
|||
fn clear(&mut self) { self.map.clear() }
|
||||
}
|
||||
|
||||
impl BaseIter<uint> for SmallIntSet {
|
||||
/// Visit all values in order
|
||||
fn each(&self, f: &fn(&uint) -> bool) -> bool { self.map.each_key(f) }
|
||||
fn size_hint(&self) -> Option<uint> { Some(self.len()) }
|
||||
}
|
||||
|
||||
impl Set<uint> for SmallIntSet {
|
||||
/// Return true if the set contains a value
|
||||
fn contains(&self, value: &uint) -> bool { self.map.contains_key(value) }
|
||||
|
|
@ -233,12 +223,14 @@ impl Set<uint> for SmallIntSet {
|
|||
/// Return true if the set has no elements in common with `other`.
|
||||
/// This is equivalent to checking for an empty uintersection.
|
||||
fn is_disjoint(&self, other: &SmallIntSet) -> bool {
|
||||
old_iter::all(self, |v| !other.contains(v))
|
||||
for self.each |v| { if other.contains(v) { return false } }
|
||||
true
|
||||
}
|
||||
|
||||
/// Return true if the set is a subset of another
|
||||
fn is_subset(&self, other: &SmallIntSet) -> bool {
|
||||
old_iter::all(self, |v| other.contains(v))
|
||||
for self.each |v| { if !other.contains(v) { return false } }
|
||||
true
|
||||
}
|
||||
|
||||
/// Return true if the set is a superset of another
|
||||
|
|
@ -286,11 +278,13 @@ impl Set<uint> for SmallIntSet {
|
|||
impl SmallIntSet {
|
||||
/// Create an empty SmallIntSet
|
||||
pub fn new() -> SmallIntSet { SmallIntSet{map: SmallIntMap::new()} }
|
||||
|
||||
/// Visit all values in order
|
||||
pub fn each(&self, f: &fn(&uint) -> bool) -> bool { self.map.each_key(f) }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use core::prelude::*;
|
||||
|
||||
use super::SmallIntMap;
|
||||
|
||||
|
|
@ -385,12 +379,9 @@ mod tests {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test_set {
|
||||
use core::prelude::*;
|
||||
|
||||
use super::SmallIntSet;
|
||||
|
||||
use core::vec;
|
||||
|
||||
#[test]
|
||||
fn test_disjoint() {
|
||||
let mut xs = SmallIntSet::new();
|
||||
|
|
@ -462,7 +453,7 @@ mod test_set {
|
|||
let mut i = 0;
|
||||
let expected = [3, 5, 11, 77];
|
||||
for a.intersection(&b) |x| {
|
||||
assert!(vec::contains(expected, x));
|
||||
assert!(expected.contains(x));
|
||||
i += 1
|
||||
}
|
||||
assert_eq!(i, expected.len());
|
||||
|
|
@ -485,7 +476,7 @@ mod test_set {
|
|||
let mut i = 0;
|
||||
let expected = [1, 5, 11];
|
||||
for a.difference(&b) |x| {
|
||||
assert!(vec::contains(expected, x));
|
||||
assert!(expected.contains(x));
|
||||
i += 1
|
||||
}
|
||||
assert_eq!(i, expected.len());
|
||||
|
|
@ -510,7 +501,7 @@ mod test_set {
|
|||
let mut i = 0;
|
||||
let expected = [1, 5, 11, 14, 22];
|
||||
for a.symmetric_difference(&b) |x| {
|
||||
assert!(vec::contains(expected, x));
|
||||
assert!(expected.contains(x));
|
||||
i += 1
|
||||
}
|
||||
assert_eq!(i, expected.len());
|
||||
|
|
@ -539,7 +530,7 @@ mod test_set {
|
|||
let mut i = 0;
|
||||
let expected = [1, 3, 5, 9, 11, 13, 16, 19, 24];
|
||||
for a.union(&b) |x| {
|
||||
assert!(vec::contains(expected, x));
|
||||
assert!(expected.contains(x));
|
||||
i += 1
|
||||
}
|
||||
assert_eq!(i, expected.len());
|
||||
|
|
|
|||
|
|
@ -10,12 +10,11 @@
|
|||
|
||||
//! Sorting methods
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::cmp::{Eq, Ord};
|
||||
use core::uint;
|
||||
use core::util::swap;
|
||||
use core::vec;
|
||||
use std::cmp::{Eq, Ord};
|
||||
use std::uint;
|
||||
use std::util::swap;
|
||||
use std::vec;
|
||||
|
||||
type Le<'self, T> = &'self fn(v1: &T, v2: &T) -> bool;
|
||||
|
||||
|
|
@ -42,7 +41,8 @@ pub fn merge_sort<T:Copy>(v: &[T], le: Le<T>) -> ~[T] {
|
|||
let mid = v_len / 2 + begin;
|
||||
let a = (begin, mid);
|
||||
let b = (mid, end);
|
||||
return merge(le, merge_sort_(v, a, le), merge_sort_(v, b, le));
|
||||
return merge(|x,y| le(x,y), merge_sort_(v, a, |x,y| le(x,y)),
|
||||
merge_sort_(v, b, |x,y| le(x,y)));
|
||||
}
|
||||
|
||||
fn merge<T:Copy>(le: Le<T>, a: &[T], b: &[T]) -> ~[T] {
|
||||
|
|
@ -57,25 +57,25 @@ pub fn merge_sort<T:Copy>(v: &[T], le: Le<T>) -> ~[T] {
|
|||
a_ix += 1;
|
||||
} else { rs.push(copy b[b_ix]); b_ix += 1; }
|
||||
}
|
||||
rs.push_all(vec::slice(a, a_ix, a_len));
|
||||
rs.push_all(vec::slice(b, b_ix, b_len));
|
||||
rs.push_all(a.slice(a_ix, a_len));
|
||||
rs.push_all(b.slice(b_ix, b_len));
|
||||
rs
|
||||
}
|
||||
}
|
||||
|
||||
fn part<T>(arr: &mut [T], left: uint,
|
||||
right: uint, pivot: uint, compare_func: Le<T>) -> uint {
|
||||
vec::swap(arr, pivot, right);
|
||||
arr.swap(pivot, right);
|
||||
let mut storage_index: uint = left;
|
||||
let mut i: uint = left;
|
||||
while i < right {
|
||||
if compare_func(&arr[i], &arr[right]) {
|
||||
vec::swap(arr, i, storage_index);
|
||||
arr.swap(i, storage_index);
|
||||
storage_index += 1;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
vec::swap(arr, storage_index, right);
|
||||
arr.swap(storage_index, right);
|
||||
return storage_index;
|
||||
}
|
||||
|
||||
|
|
@ -83,10 +83,10 @@ fn qsort<T>(arr: &mut [T], left: uint,
|
|||
right: uint, compare_func: Le<T>) {
|
||||
if right > left {
|
||||
let pivot = (left + right) / 2u;
|
||||
let new_pivot = part::<T>(arr, left, right, pivot, compare_func);
|
||||
let new_pivot = part::<T>(arr, left, right, pivot, |x,y| compare_func(x,y));
|
||||
if new_pivot != 0u {
|
||||
// Need to do this check before recursing due to overflow
|
||||
qsort::<T>(arr, left, new_pivot - 1u, compare_func);
|
||||
qsort::<T>(arr, left, new_pivot - 1u, |x,y| compare_func(x,y));
|
||||
}
|
||||
qsort::<T>(arr, new_pivot + 1u, right, compare_func);
|
||||
}
|
||||
|
|
@ -120,29 +120,29 @@ fn qsort3<T:Copy + Ord + Eq>(arr: &mut [T], left: int, right: int) {
|
|||
j -= 1;
|
||||
}
|
||||
if i >= j { break; }
|
||||
vec::swap(arr, i as uint, j as uint);
|
||||
arr.swap(i as uint, j as uint);
|
||||
if arr[i] == v {
|
||||
p += 1;
|
||||
vec::swap(arr, p as uint, i as uint);
|
||||
arr.swap(p as uint, i as uint);
|
||||
}
|
||||
if v == arr[j] {
|
||||
q -= 1;
|
||||
vec::swap(arr, j as uint, q as uint);
|
||||
arr.swap(j as uint, q as uint);
|
||||
}
|
||||
}
|
||||
vec::swap(arr, i as uint, right as uint);
|
||||
arr.swap(i as uint, right as uint);
|
||||
j = i - 1;
|
||||
i += 1;
|
||||
let mut k: int = left;
|
||||
while k < p {
|
||||
vec::swap(arr, k as uint, j as uint);
|
||||
arr.swap(k as uint, j as uint);
|
||||
k += 1;
|
||||
j -= 1;
|
||||
if k == arr.len() as int { break; }
|
||||
}
|
||||
k = right - 1;
|
||||
while k > q {
|
||||
vec::swap(arr, i as uint, k as uint);
|
||||
arr.swap(i as uint, k as uint);
|
||||
k -= 1;
|
||||
i += 1;
|
||||
if k == 0 { break; }
|
||||
|
|
@ -201,12 +201,12 @@ pub fn tim_sort<T:Copy + Ord>(array: &mut [T]) {
|
|||
loop {
|
||||
let run_len: uint = {
|
||||
// This scope contains the slice `arr` here:
|
||||
let arr = vec::mut_slice(array, idx, size);
|
||||
let arr = array.mut_slice(idx, size);
|
||||
let mut run_len: uint = count_run_ascending(arr);
|
||||
|
||||
if run_len < min_run {
|
||||
let force = if remaining <= min_run {remaining} else {min_run};
|
||||
let slice = vec::mut_slice(arr, 0, force);
|
||||
let slice = arr.mut_slice(0, force);
|
||||
binarysort(slice, run_len);
|
||||
run_len = force;
|
||||
}
|
||||
|
|
@ -259,7 +259,7 @@ fn binarysort<T:Copy + Ord>(array: &mut [T], start: uint) {
|
|||
fn reverse_slice<T>(v: &mut [T], start: uint, end:uint) {
|
||||
let mut i = start;
|
||||
while i < end / 2 {
|
||||
vec::swap(v, i, end - i - 1);
|
||||
v.swap(i, end - i - 1);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -443,14 +443,14 @@ impl<T:Copy + Ord> MergeState<T> {
|
|||
}
|
||||
|
||||
let k = { // constrain lifetime of slice below
|
||||
let slice = vec::slice(array, b1, b1+l1);
|
||||
let slice = array.slice(b1, b1+l1);
|
||||
gallop_right(&array[b2], slice, 0)
|
||||
};
|
||||
b1 += k;
|
||||
l1 -= k;
|
||||
if l1 != 0 {
|
||||
let l2 = { // constrain lifetime of slice below
|
||||
let slice = vec::slice(array, b2, b2+l2);
|
||||
let slice = array.slice(b2, b2+l2);
|
||||
gallop_left(&array[b1+l1-1],slice,l2-1)
|
||||
};
|
||||
if l2 > 0 {
|
||||
|
|
@ -479,7 +479,7 @@ impl<T:Copy + Ord> MergeState<T> {
|
|||
let mut len1 = len1;
|
||||
let mut len2 = len2;
|
||||
|
||||
vec::swap(array, dest, c2);
|
||||
array.swap(dest, c2);
|
||||
dest += 1; c2 += 1; len2 -= 1;
|
||||
|
||||
if len2 == 0 {
|
||||
|
|
@ -501,7 +501,7 @@ impl<T:Copy + Ord> MergeState<T> {
|
|||
loop {
|
||||
assert!(len1 > 1 && len2 != 0);
|
||||
if array[c2] < tmp[c1] {
|
||||
vec::swap(array, dest, c2);
|
||||
array.swap(dest, c2);
|
||||
dest += 1; c2 += 1; len2 -= 1;
|
||||
count2 += 1; count1 = 0;
|
||||
if len2 == 0 {
|
||||
|
|
@ -526,7 +526,7 @@ impl<T:Copy + Ord> MergeState<T> {
|
|||
assert!(len1 > 1 && len2 != 0);
|
||||
|
||||
count1 = {
|
||||
let tmp_view = vec::slice(tmp, c1, c1+len1);
|
||||
let tmp_view = tmp.slice(c1, c1+len1);
|
||||
gallop_right(&array[c2], tmp_view, 0)
|
||||
};
|
||||
if count1 != 0 {
|
||||
|
|
@ -534,12 +534,12 @@ impl<T:Copy + Ord> MergeState<T> {
|
|||
dest += count1; c1 += count1; len1 -= count1;
|
||||
if len1 <= 1 { break_outer = true; break; }
|
||||
}
|
||||
vec::swap(array, dest, c2);
|
||||
array.swap(dest, c2);
|
||||
dest += 1; c2 += 1; len2 -= 1;
|
||||
if len2 == 0 { break_outer = true; break; }
|
||||
|
||||
count2 = {
|
||||
let tmp_view = vec::slice(array, c2, c2+len2);
|
||||
let tmp_view = array.slice(c2, c2+len2);
|
||||
gallop_left(&tmp[c1], tmp_view, 0)
|
||||
};
|
||||
if count2 != 0 {
|
||||
|
|
@ -589,7 +589,7 @@ impl<T:Copy + Ord> MergeState<T> {
|
|||
let mut len1 = len1;
|
||||
let mut len2 = len2;
|
||||
|
||||
vec::swap(array, dest, c1);
|
||||
array.swap(dest, c1);
|
||||
dest -= 1; c1 -= 1; len1 -= 1;
|
||||
|
||||
if len1 == 0 {
|
||||
|
|
@ -613,7 +613,7 @@ impl<T:Copy + Ord> MergeState<T> {
|
|||
loop {
|
||||
assert!(len1 != 0 && len2 > 1);
|
||||
if tmp[c2] < array[c1] {
|
||||
vec::swap(array, dest, c1);
|
||||
array.swap(dest, c1);
|
||||
dest -= 1; c1 -= 1; len1 -= 1;
|
||||
count1 += 1; count2 = 0;
|
||||
if len1 == 0 {
|
||||
|
|
@ -638,7 +638,7 @@ impl<T:Copy + Ord> MergeState<T> {
|
|||
assert!(len2 > 1 && len1 != 0);
|
||||
|
||||
{ // constrain scope of tmp_view:
|
||||
let tmp_view = vec::mut_slice (array, base1, base1+len1);
|
||||
let tmp_view = array.mut_slice(base1, base1+len1);
|
||||
count1 = len1 - gallop_right(
|
||||
&tmp[c2], tmp_view, len1-1);
|
||||
}
|
||||
|
|
@ -655,7 +655,7 @@ impl<T:Copy + Ord> MergeState<T> {
|
|||
|
||||
let count2;
|
||||
{ // constrain scope of tmp_view
|
||||
let tmp_view = vec::mut_slice(tmp, 0, len2);
|
||||
let tmp_view = tmp.mut_slice(0, len2);
|
||||
count2 = len2 - gallop_left(&array[c1],
|
||||
tmp_view,
|
||||
len2-1);
|
||||
|
|
@ -666,7 +666,7 @@ impl<T:Copy + Ord> MergeState<T> {
|
|||
copy_vec(array, dest+1, tmp.slice(c2+1, c2+1+count2));
|
||||
if len2 <= 1 { break_outer = true; break; }
|
||||
}
|
||||
vec::swap(array, dest, c1);
|
||||
array.swap(dest, c1);
|
||||
dest -= 1; c1 -= 1; len1 -= 1;
|
||||
if len1 == 0 { break_outer = true; break; }
|
||||
min_gallop -= 1;
|
||||
|
|
@ -731,7 +731,7 @@ fn copy_vec<T:Copy>(dest: &mut [T],
|
|||
from: &[T]) {
|
||||
assert!(s1+from.len() <= dest.len());
|
||||
|
||||
for from.eachi |i, v| {
|
||||
for from.iter().enumerate().advance |(i, v)| {
|
||||
dest[s1+i] = copy *v;
|
||||
}
|
||||
}
|
||||
|
|
@ -743,7 +743,7 @@ fn shift_vec<T:Copy>(dest: &mut [T],
|
|||
len: uint) {
|
||||
assert!(s1+len <= dest.len());
|
||||
|
||||
let tmp = dest.slice(s2, s2+len).to_vec();
|
||||
let tmp = dest.slice(s2, s2+len).to_owned();
|
||||
copy_vec(dest, s1, tmp);
|
||||
}
|
||||
|
||||
|
|
@ -790,12 +790,11 @@ mod test_qsort3 {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test_qsort {
|
||||
use core::prelude::*;
|
||||
|
||||
use sort::*;
|
||||
|
||||
use core::int;
|
||||
use core::vec;
|
||||
use std::int;
|
||||
use std::vec;
|
||||
|
||||
fn check_sort(v1: &mut [int], v2: &mut [int]) {
|
||||
let len = v1.len();
|
||||
|
|
@ -846,7 +845,7 @@ mod test_qsort {
|
|||
let immut_names = names;
|
||||
|
||||
let pairs = vec::zip_slice(expected, immut_names);
|
||||
for pairs.each |p| {
|
||||
for pairs.iter().advance |p| {
|
||||
let (a, b) = *p;
|
||||
debug!("%d %d", a, b);
|
||||
assert_eq!(a, b);
|
||||
|
|
@ -856,7 +855,6 @@ mod test_qsort {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use core::prelude::*;
|
||||
|
||||
use sort::*;
|
||||
|
||||
|
|
@ -923,12 +921,11 @@ mod tests {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test_tim_sort {
|
||||
use core::prelude::*;
|
||||
|
||||
use sort::tim_sort;
|
||||
use core::rand::RngUtil;
|
||||
use core::rand;
|
||||
use core::vec;
|
||||
use std::rand::RngUtil;
|
||||
use std::rand;
|
||||
use std::vec;
|
||||
|
||||
struct CVal {
|
||||
val: float,
|
||||
|
|
@ -1018,15 +1015,14 @@ mod test_tim_sort {
|
|||
|
||||
#[cfg(test)]
|
||||
mod big_tests {
|
||||
use core::prelude::*;
|
||||
|
||||
use sort::*;
|
||||
|
||||
use core::local_data;
|
||||
use core::rand::RngUtil;
|
||||
use core::rand;
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use std::local_data;
|
||||
use std::rand::RngUtil;
|
||||
use std::rand;
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
|
||||
#[test]
|
||||
fn test_unique() {
|
||||
|
|
@ -1053,7 +1049,7 @@ mod big_tests {
|
|||
fn makeRange(n: uint) -> ~[uint] {
|
||||
let one = do vec::from_fn(n) |i| { i };
|
||||
let mut two = copy one;
|
||||
vec::reverse(two);
|
||||
two.reverse();
|
||||
vec::append(two, one)
|
||||
}
|
||||
|
||||
|
|
@ -1077,7 +1073,7 @@ mod big_tests {
|
|||
tim_sort(arr); // *sort
|
||||
isSorted(arr);
|
||||
|
||||
vec::reverse(arr);
|
||||
arr.reverse();
|
||||
tim_sort(arr); // \sort
|
||||
isSorted(arr);
|
||||
|
||||
|
|
@ -1087,7 +1083,7 @@ mod big_tests {
|
|||
for 3.times {
|
||||
let i1 = rng.gen_uint_range(0, n);
|
||||
let i2 = rng.gen_uint_range(0, n);
|
||||
vec::swap(arr, i1, i2);
|
||||
arr.swap(i1, i2);
|
||||
}
|
||||
tim_sort(arr); // 3sort
|
||||
isSorted(arr);
|
||||
|
|
@ -1111,7 +1107,7 @@ mod big_tests {
|
|||
isSorted(arr);
|
||||
|
||||
let mut arr = if n > 4 {
|
||||
let part = vec::slice(arr, 0, 4);
|
||||
let part = arr.slice(0, 4);
|
||||
multiplyVec(part, n)
|
||||
} else { arr };
|
||||
tim_sort(arr); // ~sort
|
||||
|
|
@ -1149,7 +1145,7 @@ mod big_tests {
|
|||
tim_sort(arr); // *sort
|
||||
isSorted(arr);
|
||||
|
||||
vec::reverse(arr);
|
||||
arr.reverse();
|
||||
tim_sort(arr); // \sort
|
||||
isSorted(arr);
|
||||
|
||||
|
|
@ -1159,7 +1155,7 @@ mod big_tests {
|
|||
for 3.times {
|
||||
let i1 = rng.gen_uint_range(0, n);
|
||||
let i2 = rng.gen_uint_range(0, n);
|
||||
vec::swap(arr, i1, i2);
|
||||
arr.swap(i1, i2);
|
||||
}
|
||||
tim_sort(arr); // 3sort
|
||||
isSorted(arr);
|
||||
|
|
@ -1183,7 +1179,7 @@ mod big_tests {
|
|||
isSorted(arr);
|
||||
|
||||
let mut arr = if n > 4 {
|
||||
let part = vec::slice(arr, 0, 4);
|
||||
let part = arr.slice(0, 4);
|
||||
multiplyVec(part, n)
|
||||
} else { arr };
|
||||
tim_sort(arr); // ~sort
|
||||
|
|
@ -1202,12 +1198,12 @@ mod big_tests {
|
|||
|
||||
struct LVal<'self> {
|
||||
val: uint,
|
||||
key: &'self fn(@uint),
|
||||
key: &'self fn:Copy(@uint),
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
impl<'self> Drop for LVal<'self> {
|
||||
fn finalize(&self) {
|
||||
fn drop(&self) {
|
||||
let x = unsafe { local_data::local_data_get(self.key) };
|
||||
match x {
|
||||
Some(@y) => {
|
||||
|
|
|
|||
|
|
@ -10,12 +10,11 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::f64;
|
||||
use core::cmp;
|
||||
use core::num;
|
||||
use core::vec;
|
||||
use std::f64;
|
||||
use std::cmp;
|
||||
use std::num;
|
||||
use std::vec;
|
||||
use sort;
|
||||
|
||||
// NB: this can probably be rewritten in terms of num::Num
|
||||
|
|
@ -72,7 +71,7 @@ impl<'self> Stats for &'self [f64] {
|
|||
} else {
|
||||
let mean = self.mean();
|
||||
let mut v = 0.0;
|
||||
for self.each |s| {
|
||||
for self.iter().advance |s| {
|
||||
let x = *s - mean;
|
||||
v += x*x;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,14 +15,13 @@
|
|||
* in std.
|
||||
*/
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::borrow;
|
||||
use core::comm;
|
||||
use core::task;
|
||||
use core::unstable::sync::{Exclusive, exclusive, UnsafeAtomicRcBox};
|
||||
use core::unstable::atomics;
|
||||
use core::util;
|
||||
use std::borrow;
|
||||
use std::comm;
|
||||
use std::task;
|
||||
use std::unstable::sync::{Exclusive, exclusive, UnsafeAtomicRcBox};
|
||||
use std::unstable::atomics;
|
||||
use std::util;
|
||||
|
||||
/****************************************************************************
|
||||
* Internals
|
||||
|
|
@ -86,7 +85,7 @@ struct SemInner<Q> {
|
|||
struct Sem<Q>(Exclusive<SemInner<Q>>);
|
||||
|
||||
#[doc(hidden)]
|
||||
fn new_sem<Q:Owned>(count: int, q: Q) -> Sem<Q> {
|
||||
fn new_sem<Q:Send>(count: int, q: Q) -> Sem<Q> {
|
||||
Sem(exclusive(SemInner {
|
||||
count: count, waiters: new_waitqueue(), blocked: q }))
|
||||
}
|
||||
|
|
@ -101,7 +100,7 @@ fn new_sem_and_signal(count: int, num_condvars: uint)
|
|||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl<Q:Owned> Sem<Q> {
|
||||
impl<Q:Send> Sem<Q> {
|
||||
pub fn acquire(&self) {
|
||||
unsafe {
|
||||
let mut waiter_nobe = None;
|
||||
|
|
@ -153,7 +152,7 @@ impl Sem<()> {
|
|||
|
||||
#[doc(hidden)]
|
||||
impl Sem<~[Waitqueue]> {
|
||||
pub fn access<U>(&self, blk: &fn() -> U) -> U {
|
||||
pub fn access_waitqueue<U>(&self, blk: &fn() -> U) -> U {
|
||||
let mut release = None;
|
||||
unsafe {
|
||||
do task::unkillable {
|
||||
|
|
@ -175,8 +174,8 @@ struct SemReleaseGeneric<'self, Q> { sem: &'self Sem<Q> }
|
|||
|
||||
#[doc(hidden)]
|
||||
#[unsafe_destructor]
|
||||
impl<'self, Q:Owned> Drop for SemReleaseGeneric<'self, Q> {
|
||||
fn finalize(&self) {
|
||||
impl<'self, Q:Send> Drop for SemReleaseGeneric<'self, Q> {
|
||||
fn drop(&self) {
|
||||
self.sem.release();
|
||||
}
|
||||
}
|
||||
|
|
@ -219,7 +218,7 @@ pub struct Condvar<'self> {
|
|||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
impl<'self> Drop for Condvar<'self> { fn finalize(&self) {} }
|
||||
impl<'self> Drop for Condvar<'self> { fn drop(&self) {} }
|
||||
|
||||
impl<'self> Condvar<'self> {
|
||||
/**
|
||||
|
|
@ -295,7 +294,7 @@ impl<'self> Condvar<'self> {
|
|||
|
||||
#[unsafe_destructor]
|
||||
impl<'self> Drop for CondvarReacquire<'self> {
|
||||
fn finalize(&self) {
|
||||
fn drop(&self) {
|
||||
unsafe {
|
||||
// Needs to succeed, instead of itself dying.
|
||||
do task::unkillable {
|
||||
|
|
@ -381,7 +380,7 @@ impl Sem<~[Waitqueue]> {
|
|||
// The only other places that condvars get built are rwlock.write_cond()
|
||||
// and rwlock_write_mode.
|
||||
pub fn access_cond<U>(&self, blk: &fn(c: &Condvar) -> U) -> U {
|
||||
do self.access {
|
||||
do self.access_waitqueue {
|
||||
blk(&Condvar { sem: self, order: Nothing })
|
||||
}
|
||||
}
|
||||
|
|
@ -456,7 +455,9 @@ impl Clone for Mutex {
|
|||
|
||||
impl Mutex {
|
||||
/// Run a function with ownership of the mutex.
|
||||
pub fn lock<U>(&self, blk: &fn() -> U) -> U { (&self.sem).access(blk) }
|
||||
pub fn lock<U>(&self, blk: &fn() -> U) -> U {
|
||||
(&self.sem).access_waitqueue(blk)
|
||||
}
|
||||
|
||||
/// Run a function with ownership of the mutex and a handle to a condvar.
|
||||
pub fn lock_cond<U>(&self, blk: &fn(c: &Condvar) -> U) -> U {
|
||||
|
|
@ -559,9 +560,11 @@ impl RWlock {
|
|||
unsafe {
|
||||
do task::unkillable {
|
||||
(&self.order_lock).acquire();
|
||||
do (&self.access_lock).access {
|
||||
do (&self.access_lock).access_waitqueue {
|
||||
(&self.order_lock).release();
|
||||
task::rekillable(blk)
|
||||
do task::rekillable {
|
||||
blk()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -689,7 +692,7 @@ struct RWlockReleaseRead<'self> {
|
|||
#[doc(hidden)]
|
||||
#[unsafe_destructor]
|
||||
impl<'self> Drop for RWlockReleaseRead<'self> {
|
||||
fn finalize(&self) {
|
||||
fn drop(&self) {
|
||||
unsafe {
|
||||
do task::unkillable {
|
||||
let state = &mut *self.lock.state.get();
|
||||
|
|
@ -726,7 +729,7 @@ struct RWlockReleaseDowngrade<'self> {
|
|||
#[doc(hidden)]
|
||||
#[unsafe_destructor]
|
||||
impl<'self> Drop for RWlockReleaseDowngrade<'self> {
|
||||
fn finalize(&self) {
|
||||
fn drop(&self) {
|
||||
unsafe {
|
||||
do task::unkillable {
|
||||
let writer_or_last_reader;
|
||||
|
|
@ -769,12 +772,12 @@ fn RWlockReleaseDowngrade<'r>(lock: &'r RWlock)
|
|||
/// The "write permission" token used for rwlock.write_downgrade().
|
||||
pub struct RWlockWriteMode<'self> { priv lock: &'self RWlock }
|
||||
#[unsafe_destructor]
|
||||
impl<'self> Drop for RWlockWriteMode<'self> { fn finalize(&self) {} }
|
||||
impl<'self> Drop for RWlockWriteMode<'self> { fn drop(&self) {} }
|
||||
|
||||
/// The "read permission" token used for rwlock.write_downgrade().
|
||||
pub struct RWlockReadMode<'self> { priv lock: &'self RWlock }
|
||||
#[unsafe_destructor]
|
||||
impl<'self> Drop for RWlockReadMode<'self> { fn finalize(&self) {} }
|
||||
impl<'self> Drop for RWlockReadMode<'self> { fn drop(&self) {} }
|
||||
|
||||
impl<'self> RWlockWriteMode<'self> {
|
||||
/// Access the pre-downgrade rwlock in write mode.
|
||||
|
|
@ -799,16 +802,14 @@ impl<'self> RWlockReadMode<'self> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use core::prelude::*;
|
||||
|
||||
use sync::*;
|
||||
|
||||
use core::cast;
|
||||
use core::cell::Cell;
|
||||
use core::comm;
|
||||
use core::result;
|
||||
use core::task;
|
||||
use core::vec;
|
||||
use std::cast;
|
||||
use std::cell::Cell;
|
||||
use std::comm;
|
||||
use std::result;
|
||||
use std::task;
|
||||
|
||||
/************************************************************************
|
||||
* Semaphore tests
|
||||
|
|
@ -994,13 +995,13 @@ mod tests {
|
|||
}
|
||||
|
||||
// wait until all children get in the mutex
|
||||
for ports.each |port| { let _ = port.recv(); }
|
||||
for ports.iter().advance |port| { let _ = port.recv(); }
|
||||
do m.lock_cond |cond| {
|
||||
let num_woken = cond.broadcast();
|
||||
assert_eq!(num_woken, num_waiters);
|
||||
}
|
||||
// wait until all children wake up
|
||||
for ports.each |port| { let _ = port.recv(); }
|
||||
for ports.iter().advance |port| { let _ = port.recv(); }
|
||||
}
|
||||
#[test]
|
||||
fn test_mutex_cond_broadcast() {
|
||||
|
|
@ -1085,7 +1086,7 @@ mod tests {
|
|||
}
|
||||
}
|
||||
}
|
||||
for sibling_convos.each |p| {
|
||||
for sibling_convos.iter().advance |p| {
|
||||
let _ = p.recv(); // wait for sibling to get in the mutex
|
||||
}
|
||||
do m2.lock { }
|
||||
|
|
@ -1094,7 +1095,8 @@ mod tests {
|
|||
};
|
||||
assert!(result.is_err());
|
||||
// child task must have finished by the time try returns
|
||||
for vec::each(p.recv()) |p| { p.recv(); } // wait on all its siblings
|
||||
let r = p.recv();
|
||||
for r.iter().advance |p| { p.recv(); } // wait on all its siblings
|
||||
do m.lock_cond |cond| {
|
||||
let woken = cond.broadcast();
|
||||
assert_eq!(woken, 0);
|
||||
|
|
@ -1104,7 +1106,7 @@ mod tests {
|
|||
}
|
||||
|
||||
impl Drop for SendOnFailure {
|
||||
fn finalize(&self) {
|
||||
fn drop(&self) {
|
||||
self.c.send(());
|
||||
}
|
||||
}
|
||||
|
|
@ -1180,12 +1182,12 @@ mod tests {
|
|||
Write => x.write(blk),
|
||||
Downgrade =>
|
||||
do x.write_downgrade |mode| {
|
||||
(&mode).write(blk);
|
||||
do mode.write { blk() };
|
||||
},
|
||||
DowngradeRead =>
|
||||
do x.write_downgrade |mode| {
|
||||
let mode = x.downgrade(mode);
|
||||
(&mode).read(blk);
|
||||
do mode.read { blk() };
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -1338,10 +1340,10 @@ mod tests {
|
|||
fn lock_cond(x: &RWlock, downgrade: bool, blk: &fn(c: &Condvar)) {
|
||||
if downgrade {
|
||||
do x.write_downgrade |mode| {
|
||||
(&mode).write_cond(blk)
|
||||
do mode.write_cond |c| { blk(c) }
|
||||
}
|
||||
} else {
|
||||
x.write_cond(blk)
|
||||
do x.write_cond |c| { blk(c) }
|
||||
}
|
||||
}
|
||||
let x = ~RWlock();
|
||||
|
|
@ -1361,13 +1363,13 @@ mod tests {
|
|||
}
|
||||
|
||||
// wait until all children get in the mutex
|
||||
for ports.each |port| { let _ = port.recv(); }
|
||||
for ports.iter().advance |port| { let _ = port.recv(); }
|
||||
do lock_cond(x, dg2) |cond| {
|
||||
let num_woken = cond.broadcast();
|
||||
assert_eq!(num_woken, num_waiters);
|
||||
}
|
||||
// wait until all children wake up
|
||||
for ports.each |port| { let _ = port.recv(); }
|
||||
for ports.iter().advance |port| { let _ = port.recv(); }
|
||||
}
|
||||
#[test]
|
||||
fn test_rwlock_cond_broadcast() {
|
||||
|
|
|
|||
|
|
@ -13,15 +13,14 @@
|
|||
/// A task pool abstraction. Useful for achieving predictable CPU
|
||||
/// parallelism.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::comm::Chan;
|
||||
use core::comm;
|
||||
use core::task::SchedMode;
|
||||
use core::task;
|
||||
use core::vec;
|
||||
use std::comm::Chan;
|
||||
use std::comm;
|
||||
use std::task::SchedMode;
|
||||
use std::task;
|
||||
use std::vec;
|
||||
|
||||
#[cfg(test)] use core::task::SingleThreaded;
|
||||
#[cfg(test)] use std::task::SingleThreaded;
|
||||
|
||||
enum Msg<T> {
|
||||
Execute(~fn(&T)),
|
||||
|
|
@ -35,8 +34,8 @@ pub struct TaskPool<T> {
|
|||
|
||||
#[unsafe_destructor]
|
||||
impl<T> Drop for TaskPool<T> {
|
||||
fn finalize(&self) {
|
||||
for self.channels.each |channel| {
|
||||
fn drop(&self) {
|
||||
for self.channels.iter().advance |channel| {
|
||||
channel.send(Quit);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,11 +10,10 @@
|
|||
|
||||
//! Temporary files and directories
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::os;
|
||||
use core::rand::RngUtil;
|
||||
use core::rand;
|
||||
use std::os;
|
||||
use std::rand::RngUtil;
|
||||
use std::rand;
|
||||
|
||||
/// Attempts to make a temporary directory inside of `tmpdir` whose name will
|
||||
/// have the suffix `suffix`. If no directory can be created, None is returned.
|
||||
|
|
@ -31,11 +30,10 @@ pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option<Path> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use core::prelude::*;
|
||||
|
||||
use tempfile::mkdtemp;
|
||||
|
||||
use core::os;
|
||||
use std::os;
|
||||
|
||||
#[test]
|
||||
fn test_mkdtemp() {
|
||||
|
|
@ -44,12 +42,12 @@ mod tests {
|
|||
assert!(p.to_str().ends_with("foobar"));
|
||||
}
|
||||
|
||||
// Ideally these would be in core::os but then core would need
|
||||
// Ideally these would be in std::os but then core would need
|
||||
// to depend on std
|
||||
#[test]
|
||||
fn recursive_mkdir_rel() {
|
||||
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
|
||||
use core::os;
|
||||
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
|
||||
use std::os;
|
||||
|
||||
let root = mkdtemp(&os::tmpdir(), "recursive_mkdir_rel").
|
||||
expect("recursive_mkdir_rel");
|
||||
|
|
@ -67,8 +65,8 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn recursive_mkdir_dot() {
|
||||
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
|
||||
use core::os;
|
||||
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
|
||||
use std::os;
|
||||
|
||||
let dot = Path(".");
|
||||
assert!(os::mkdir_recursive(&dot, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
|
||||
|
|
@ -78,8 +76,8 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn recursive_mkdir_rel_2() {
|
||||
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
|
||||
use core::os;
|
||||
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
|
||||
use std::os;
|
||||
|
||||
let root = mkdtemp(&os::tmpdir(), "recursive_mkdir_rel_2").
|
||||
expect("recursive_mkdir_rel_2");
|
||||
|
|
@ -102,8 +100,8 @@ mod tests {
|
|||
// Ideally this would be in core, but needs mkdtemp
|
||||
#[test]
|
||||
pub fn test_rmdir_recursive_ok() {
|
||||
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
|
||||
use core::os;
|
||||
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
|
||||
use std::os;
|
||||
|
||||
let rwx = (S_IRUSR | S_IWUSR | S_IXUSR) as i32;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,47 +12,49 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::io;
|
||||
use core::os;
|
||||
use std::io;
|
||||
|
||||
use terminfo::*;
|
||||
use terminfo::searcher::open;
|
||||
use terminfo::parser::compiled::parse;
|
||||
use terminfo::parm::{expand, Number, Variables};
|
||||
#[cfg(not(target_os = "win32"))] use std::os;
|
||||
#[cfg(not(target_os = "win32"))] use terminfo::*;
|
||||
#[cfg(not(target_os = "win32"))] use terminfo::searcher::open;
|
||||
#[cfg(not(target_os = "win32"))] use terminfo::parser::compiled::parse;
|
||||
#[cfg(not(target_os = "win32"))] use terminfo::parm::{expand, Number, Variables};
|
||||
|
||||
// FIXME (#2807): Windows support.
|
||||
|
||||
pub static color_black: u8 = 0u8;
|
||||
pub static color_red: u8 = 1u8;
|
||||
pub static color_green: u8 = 2u8;
|
||||
pub static color_yellow: u8 = 3u8;
|
||||
pub static color_blue: u8 = 4u8;
|
||||
pub static color_magenta: u8 = 5u8;
|
||||
pub static color_cyan: u8 = 6u8;
|
||||
pub static color_light_gray: u8 = 7u8;
|
||||
pub static color_light_grey: u8 = 7u8;
|
||||
pub static color_dark_gray: u8 = 8u8;
|
||||
pub static color_dark_grey: u8 = 8u8;
|
||||
pub static color_bright_red: u8 = 9u8;
|
||||
pub static color_bright_green: u8 = 10u8;
|
||||
pub static color_bright_yellow: u8 = 11u8;
|
||||
pub static color_bright_blue: u8 = 12u8;
|
||||
pub static color_bright_magenta: u8 = 13u8;
|
||||
pub static color_bright_cyan: u8 = 14u8;
|
||||
pub static color_bright_white: u8 = 15u8;
|
||||
pub mod color {
|
||||
pub type Color = u16;
|
||||
|
||||
pub static black: Color = 0u16;
|
||||
pub static red: Color = 1u16;
|
||||
pub static green: Color = 2u16;
|
||||
pub static yellow: Color = 3u16;
|
||||
pub static blue: Color = 4u16;
|
||||
pub static magenta: Color = 5u16;
|
||||
pub static cyan: Color = 6u16;
|
||||
pub static white: Color = 7u16;
|
||||
|
||||
pub static bright_black: Color = 8u16;
|
||||
pub static bright_red: Color = 9u16;
|
||||
pub static bright_green: Color = 10u16;
|
||||
pub static bright_yellow: Color = 11u16;
|
||||
pub static bright_blue: Color = 12u16;
|
||||
pub static bright_magenta: Color = 13u16;
|
||||
pub static bright_cyan: Color = 14u16;
|
||||
pub static bright_white: Color = 15u16;
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "win32"))]
|
||||
pub struct Terminal {
|
||||
color_supported: bool,
|
||||
num_colors: u16,
|
||||
priv out: @io::Writer,
|
||||
priv ti: ~TermInfo
|
||||
}
|
||||
|
||||
#[cfg(target_os = "win32")]
|
||||
pub struct Terminal {
|
||||
color_supported: bool,
|
||||
num_colors: u16,
|
||||
priv out: @io::Writer,
|
||||
}
|
||||
|
||||
|
|
@ -66,66 +68,86 @@ impl Terminal {
|
|||
|
||||
let entry = open(term.unwrap());
|
||||
if entry.is_err() {
|
||||
return Err(entry.get_err());
|
||||
return Err(entry.unwrap_err());
|
||||
}
|
||||
|
||||
let ti = parse(entry.get(), false);
|
||||
let ti = parse(entry.unwrap(), false);
|
||||
if ti.is_err() {
|
||||
return Err(entry.get_err());
|
||||
return Err(ti.unwrap_err());
|
||||
}
|
||||
|
||||
let mut inf = ti.get();
|
||||
let cs = *inf.numbers.find_or_insert(~"colors", 0) >= 16
|
||||
&& inf.strings.find(&~"setaf").is_some()
|
||||
&& inf.strings.find_equiv(&("setab")).is_some();
|
||||
let inf = ti.unwrap();
|
||||
let nc = if inf.strings.find_equiv(&("setaf")).is_some()
|
||||
&& inf.strings.find_equiv(&("setab")).is_some() {
|
||||
inf.numbers.find_equiv(&("colors")).map_consume_default(0, |&n| n)
|
||||
} else { 0 };
|
||||
|
||||
return Ok(Terminal {out: out, ti: inf, color_supported: cs});
|
||||
return Ok(Terminal {out: out, ti: inf, num_colors: nc});
|
||||
}
|
||||
pub fn fg(&self, color: u8) {
|
||||
if self.color_supported {
|
||||
/// Sets the foreground color to the given color.
|
||||
///
|
||||
/// If the color is a bright color, but the terminal only supports 8 colors,
|
||||
/// the corresponding normal color will be used instead.
|
||||
pub fn fg(&self, color: color::Color) {
|
||||
let color = self.dim_if_necessary(color);
|
||||
if self.num_colors > color {
|
||||
let s = expand(*self.ti.strings.find_equiv(&("setaf")).unwrap(),
|
||||
[Number(color as int)], &mut Variables::new());
|
||||
if s.is_ok() {
|
||||
self.out.write(s.get());
|
||||
self.out.write(s.unwrap());
|
||||
} else {
|
||||
warn!(s.get_err());
|
||||
warn!("%s", s.unwrap_err());
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn bg(&self, color: u8) {
|
||||
if self.color_supported {
|
||||
/// Sets the background color to the given color.
|
||||
///
|
||||
/// If the color is a bright color, but the terminal only supports 8 colors,
|
||||
/// the corresponding normal color will be used instead.
|
||||
pub fn bg(&self, color: color::Color) {
|
||||
let color = self.dim_if_necessary(color);
|
||||
if self.num_colors > color {
|
||||
let s = expand(*self.ti.strings.find_equiv(&("setab")).unwrap(),
|
||||
[Number(color as int)], &mut Variables::new());
|
||||
if s.is_ok() {
|
||||
self.out.write(s.get());
|
||||
self.out.write(s.unwrap());
|
||||
} else {
|
||||
warn!(s.get_err());
|
||||
warn!("%s", s.unwrap_err());
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn reset(&self) {
|
||||
if self.color_supported {
|
||||
let mut vars = Variables::new();
|
||||
let s = expand(*self.ti.strings.find_equiv(&("op")).unwrap(), [], &mut vars);
|
||||
if s.is_ok() {
|
||||
self.out.write(s.get());
|
||||
} else {
|
||||
warn!(s.get_err());
|
||||
}
|
||||
let mut vars = Variables::new();
|
||||
let s = do self.ti.strings.find_equiv(&("op"))
|
||||
.map_consume_default(Err(~"can't find terminfo capability `op`")) |&op| {
|
||||
expand(op, [], &mut vars)
|
||||
};
|
||||
if s.is_ok() {
|
||||
self.out.write(s.unwrap());
|
||||
} else if self.num_colors > 0 {
|
||||
warn!("%s", s.unwrap_err());
|
||||
} else {
|
||||
debug!("%s", s.unwrap_err());
|
||||
}
|
||||
}
|
||||
|
||||
priv fn dim_if_necessary(&self, color: color::Color) -> color::Color {
|
||||
if color >= self.num_colors && color >= 8 && color < 16 {
|
||||
color-8
|
||||
} else { color }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "win32")]
|
||||
impl Terminal {
|
||||
pub fn new(out: @io::Writer) -> Result<Terminal, ~str> {
|
||||
return Ok(Terminal {out: out, color_supported: false});
|
||||
return Ok(Terminal {out: out, num_colors: 0});
|
||||
}
|
||||
|
||||
pub fn fg(&self, color: u8) {
|
||||
pub fn fg(&self, _color: color::Color) {
|
||||
}
|
||||
|
||||
pub fn bg(&self, color: u8) {
|
||||
pub fn bg(&self, _color: color::Color) {
|
||||
}
|
||||
|
||||
pub fn reset(&self) {
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
//! Parameterized string expansion
|
||||
|
||||
use core::prelude::*;
|
||||
use core::{char, int, vec};
|
||||
use core::iterator::IteratorUtil;
|
||||
use std::{char, vec, util};
|
||||
use std::num::strconv::{SignNone,SignNeg,SignAll,int_to_str_bytes_common};
|
||||
use std::iterator::IteratorUtil;
|
||||
|
||||
#[deriving(Eq)]
|
||||
enum States {
|
||||
|
|
@ -23,13 +23,21 @@ enum States {
|
|||
PushParam,
|
||||
CharConstant,
|
||||
CharClose,
|
||||
IntConstant,
|
||||
IntConstant(int),
|
||||
FormatPattern(Flags, FormatState),
|
||||
SeekIfElse(int),
|
||||
SeekIfElsePercent(int),
|
||||
SeekIfEnd(int),
|
||||
SeekIfEndPercent(int)
|
||||
}
|
||||
|
||||
#[deriving(Eq)]
|
||||
enum FormatState {
|
||||
FormatStateFlags,
|
||||
FormatStateWidth,
|
||||
FormatStatePrecision
|
||||
}
|
||||
|
||||
/// Types of parameters a capability can use
|
||||
pub enum Param {
|
||||
String(~str),
|
||||
|
|
@ -71,8 +79,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
|
|||
|
||||
let mut stack: ~[Param] = ~[];
|
||||
|
||||
let mut intstate = ~[];
|
||||
|
||||
// Copy parameters into a local vector for mutability
|
||||
let mut mparams = [Number(0), ..9];
|
||||
for mparams.mut_iter().zip(params.iter()).advance |(dst, &src)| {
|
||||
|
|
@ -100,26 +106,11 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
|
|||
_ => return Err(~"a non-char was used with %c")
|
||||
}
|
||||
} else { return Err(~"stack is empty") },
|
||||
's' => if stack.len() > 0 {
|
||||
match stack.pop() {
|
||||
String(s) => output.push_all(s.as_bytes()),
|
||||
_ => return Err(~"a non-str was used with %s")
|
||||
}
|
||||
} else { return Err(~"stack is empty") },
|
||||
'd' => if stack.len() > 0 {
|
||||
match stack.pop() {
|
||||
Number(x) => {
|
||||
let s = x.to_str();
|
||||
output.push_all(s.as_bytes())
|
||||
}
|
||||
_ => return Err(~"a non-number was used with %d")
|
||||
}
|
||||
} else { return Err(~"stack is empty") },
|
||||
'p' => state = PushParam,
|
||||
'P' => state = SetVar,
|
||||
'g' => state = GetVar,
|
||||
'\'' => state = CharConstant,
|
||||
'{' => state = IntConstant,
|
||||
'{' => state = IntConstant(0),
|
||||
'l' => if stack.len() > 0 {
|
||||
match stack.pop() {
|
||||
String(s) => stack.push(Number(s.len() as int)),
|
||||
|
|
@ -231,6 +222,30 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
|
|||
(_, _) => return Err(~"first two params not numbers with %i")
|
||||
},
|
||||
|
||||
// printf-style support for %doxXs
|
||||
'd'|'o'|'x'|'X'|'s' => if stack.len() > 0 {
|
||||
let flags = Flags::new();
|
||||
let res = format(stack.pop(), FormatOp::from_char(cur), flags);
|
||||
if res.is_err() { return res }
|
||||
output.push_all(res.unwrap())
|
||||
} else { return Err(~"stack is empty") },
|
||||
':'|'#'|' '|'.'|'0'..'9' => {
|
||||
let mut flags = Flags::new();
|
||||
let mut fstate = FormatStateFlags;
|
||||
match cur {
|
||||
':' => (),
|
||||
'#' => flags.alternate = true,
|
||||
' ' => flags.space = true,
|
||||
'.' => fstate = FormatStatePrecision,
|
||||
'0'..'9' => {
|
||||
flags.width = (cur - '0') as uint;
|
||||
fstate = FormatStateWidth;
|
||||
}
|
||||
_ => util::unreachable()
|
||||
}
|
||||
state = FormatPattern(flags, fstate);
|
||||
}
|
||||
|
||||
// conditionals
|
||||
'?' => (),
|
||||
't' => if stack.len() > 0 {
|
||||
|
|
@ -288,17 +303,61 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
|
|||
return Err(~"malformed character constant");
|
||||
}
|
||||
},
|
||||
IntConstant => {
|
||||
if cur == '}' {
|
||||
stack.push(match int::parse_bytes(intstate, 10) {
|
||||
Some(n) => Number(n),
|
||||
None => return Err(~"bad int constant")
|
||||
});
|
||||
intstate.clear();
|
||||
state = Nothing;
|
||||
} else {
|
||||
intstate.push(cur as u8);
|
||||
old_state = Nothing;
|
||||
IntConstant(i) => {
|
||||
match cur {
|
||||
'}' => {
|
||||
stack.push(Number(i));
|
||||
state = Nothing;
|
||||
}
|
||||
'0'..'9' => {
|
||||
state = IntConstant(i*10 + ((cur - '0') as int));
|
||||
old_state = Nothing;
|
||||
}
|
||||
_ => return Err(~"bad int constant")
|
||||
}
|
||||
}
|
||||
FormatPattern(ref mut flags, ref mut fstate) => {
|
||||
old_state = Nothing;
|
||||
match (*fstate, cur) {
|
||||
(_,'d')|(_,'o')|(_,'x')|(_,'X')|(_,'s') => if stack.len() > 0 {
|
||||
let res = format(stack.pop(), FormatOp::from_char(cur), *flags);
|
||||
if res.is_err() { return res }
|
||||
output.push_all(res.unwrap());
|
||||
old_state = state; // will cause state to go to Nothing
|
||||
} else { return Err(~"stack is empty") },
|
||||
(FormatStateFlags,'#') => {
|
||||
flags.alternate = true;
|
||||
}
|
||||
(FormatStateFlags,'-') => {
|
||||
flags.left = true;
|
||||
}
|
||||
(FormatStateFlags,'+') => {
|
||||
flags.sign = true;
|
||||
}
|
||||
(FormatStateFlags,' ') => {
|
||||
flags.space = true;
|
||||
}
|
||||
(FormatStateFlags,'0'..'9') => {
|
||||
flags.width = (cur - '0') as uint;
|
||||
*fstate = FormatStateWidth;
|
||||
}
|
||||
(FormatStateFlags,'.') => {
|
||||
*fstate = FormatStatePrecision;
|
||||
}
|
||||
(FormatStateWidth,'0'..'9') => {
|
||||
let old = flags.width;
|
||||
flags.width = flags.width * 10 + ((cur - '0') as uint);
|
||||
if flags.width < old { return Err(~"format width overflow") }
|
||||
}
|
||||
(FormatStateWidth,'.') => {
|
||||
*fstate = FormatStatePrecision;
|
||||
}
|
||||
(FormatStatePrecision,'0'..'9') => {
|
||||
let old = flags.precision;
|
||||
flags.precision = flags.precision * 10 + ((cur - '0') as uint);
|
||||
if flags.precision < old { return Err(~"format precision overflow") }
|
||||
}
|
||||
_ => return Err(~"invalid format specifier")
|
||||
}
|
||||
}
|
||||
SeekIfElse(level) => {
|
||||
|
|
@ -349,10 +408,153 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
|
|||
Ok(output)
|
||||
}
|
||||
|
||||
#[deriving(Eq)]
|
||||
priv struct Flags {
|
||||
width: uint,
|
||||
precision: uint,
|
||||
alternate: bool,
|
||||
left: bool,
|
||||
sign: bool,
|
||||
space: bool
|
||||
}
|
||||
|
||||
impl Flags {
|
||||
priv fn new() -> Flags {
|
||||
Flags{ width: 0, precision: 0, alternate: false,
|
||||
left: false, sign: false, space: false }
|
||||
}
|
||||
}
|
||||
|
||||
priv enum FormatOp {
|
||||
FormatDigit,
|
||||
FormatOctal,
|
||||
FormatHex,
|
||||
FormatHEX,
|
||||
FormatString
|
||||
}
|
||||
|
||||
impl FormatOp {
|
||||
priv fn from_char(c: char) -> FormatOp {
|
||||
match c {
|
||||
'd' => FormatDigit,
|
||||
'o' => FormatOctal,
|
||||
'x' => FormatHex,
|
||||
'X' => FormatHEX,
|
||||
's' => FormatString,
|
||||
_ => fail!("bad FormatOp char")
|
||||
}
|
||||
}
|
||||
priv fn to_char(self) -> char {
|
||||
match self {
|
||||
FormatDigit => 'd',
|
||||
FormatOctal => 'o',
|
||||
FormatHex => 'x',
|
||||
FormatHEX => 'X',
|
||||
FormatString => 's'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
priv fn format(val: Param, op: FormatOp, flags: Flags) -> Result<~[u8],~str> {
|
||||
let mut s = match val {
|
||||
Number(d) => {
|
||||
match op {
|
||||
FormatString => {
|
||||
return Err(~"non-number on stack with %s")
|
||||
}
|
||||
_ => {
|
||||
let radix = match op {
|
||||
FormatDigit => 10,
|
||||
FormatOctal => 8,
|
||||
FormatHex|FormatHEX => 16,
|
||||
FormatString => util::unreachable()
|
||||
};
|
||||
let mut s = ~[];
|
||||
match op {
|
||||
FormatDigit => {
|
||||
let sign = if flags.sign { SignAll } else { SignNeg };
|
||||
do int_to_str_bytes_common(d, radix, sign) |c| {
|
||||
s.push(c);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
do int_to_str_bytes_common(d as uint, radix, SignNone) |c| {
|
||||
s.push(c);
|
||||
}
|
||||
}
|
||||
};
|
||||
if flags.precision > s.len() {
|
||||
let mut s_ = vec::with_capacity(flags.precision);
|
||||
let n = flags.precision - s.len();
|
||||
s_.grow(n, &('0' as u8));
|
||||
s_.push_all_move(s);
|
||||
s = s_;
|
||||
}
|
||||
assert!(!s.is_empty(), "string conversion produced empty result");
|
||||
match op {
|
||||
FormatDigit => {
|
||||
if flags.space && !(s[0] == '-' as u8 || s[0] == '+' as u8) {
|
||||
s.unshift(' ' as u8);
|
||||
}
|
||||
}
|
||||
FormatOctal => {
|
||||
if flags.alternate && s[0] != '0' as u8 {
|
||||
s.unshift('0' as u8);
|
||||
}
|
||||
}
|
||||
FormatHex => {
|
||||
if flags.alternate {
|
||||
let s_ = util::replace(&mut s, ~['0' as u8, 'x' as u8]);
|
||||
s.push_all_move(s_);
|
||||
}
|
||||
}
|
||||
FormatHEX => {
|
||||
s = s.into_ascii().to_upper().into_bytes();
|
||||
if flags.alternate {
|
||||
let s_ = util::replace(&mut s, ~['0' as u8, 'X' as u8]);
|
||||
s.push_all_move(s_);
|
||||
}
|
||||
}
|
||||
FormatString => util::unreachable()
|
||||
}
|
||||
s
|
||||
}
|
||||
}
|
||||
}
|
||||
String(s) => {
|
||||
match op {
|
||||
FormatString => {
|
||||
let mut s = s.as_bytes_with_null_consume();
|
||||
s.pop(); // remove the null
|
||||
if flags.precision > 0 && flags.precision < s.len() {
|
||||
s.truncate(flags.precision);
|
||||
}
|
||||
s
|
||||
}
|
||||
_ => {
|
||||
return Err(fmt!("non-string on stack with %%%c", op.to_char()))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
if flags.width > s.len() {
|
||||
let n = flags.width - s.len();
|
||||
if flags.left {
|
||||
s.grow(n, &(' ' as u8));
|
||||
} else {
|
||||
let mut s_ = vec::with_capacity(flags.width);
|
||||
s_.grow(n, &(' ' as u8));
|
||||
s_.push_all_move(s);
|
||||
s = s_;
|
||||
}
|
||||
}
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use core::result::Ok;
|
||||
use std::result::Ok;
|
||||
|
||||
#[test]
|
||||
fn test_basic_setabf() {
|
||||
|
|
@ -443,4 +645,20 @@ mod test {
|
|||
assert!(res.is_ok(), res.unwrap_err());
|
||||
assert_eq!(res.unwrap(), bytes!("\\E[38;5;42m").to_owned());
|
||||
}
|
||||
|
||||
#[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"),
|
||||
[String(~"foo"), String(~"foo"), String(~"f"), String(~"foo")], vars),
|
||||
Ok(bytes!("foofoo ffo").to_owned()));
|
||||
assert_eq!(expand(bytes!("%p1%:-4.2s"), [String(~"foo")], vars),
|
||||
Ok(bytes!("fo ").to_owned()));
|
||||
|
||||
assert_eq!(expand(bytes!("%p1%d%p1%.3d%p1%5d%p1%:+d"), [Number(1)], vars),
|
||||
Ok(bytes!("1001 1+1").to_owned()));
|
||||
assert_eq!(expand(bytes!("%p1%o%p1%#o%p2%6.4x%p2%#6.4X"), [Number(15), Number(27)], vars),
|
||||
Ok(bytes!("17017 001b0X001B").to_owned()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,11 +10,10 @@
|
|||
|
||||
/// ncurses-compatible compiled terminfo format parsing (term(5))
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::{vec, int, str};
|
||||
use core::io::Reader;
|
||||
use core::hashmap::HashMap;
|
||||
use std::{vec, int, str};
|
||||
use std::io::Reader;
|
||||
use std::hashmap::HashMap;
|
||||
use super::super::TermInfo;
|
||||
|
||||
// These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
|
||||
|
|
@ -271,7 +270,7 @@ pub fn parse(file: @Reader, longnames: bool) -> Result<~TermInfo, ~str> {
|
|||
return Err(~"error: hit EOF before end of string table");
|
||||
}
|
||||
|
||||
for string_offsets.eachi |i, v| {
|
||||
for string_offsets.iter().enumerate().advance |(i, v)| {
|
||||
let offset = *v;
|
||||
if offset == 0xFFFF { // non-entry
|
||||
loop;
|
||||
|
|
@ -292,12 +291,13 @@ pub fn parse(file: @Reader, longnames: bool) -> Result<~TermInfo, ~str> {
|
|||
|
||||
|
||||
// Find the offset of the NUL we want to go to
|
||||
let nulpos = vec::position_between(string_table, offset as uint,
|
||||
string_table_bytes as uint, |&b| b == 0);
|
||||
let nulpos = string_table.slice(offset as uint, string_table_bytes as uint)
|
||||
.iter().position_(|&b| b == 0);
|
||||
match nulpos {
|
||||
Some(x) => {
|
||||
Some(len) => {
|
||||
string_map.insert(name.to_owned(),
|
||||
string_table.slice(offset as uint, x).to_owned())
|
||||
string_table.slice(offset as uint,
|
||||
offset as uint + len).to_owned())
|
||||
},
|
||||
None => {
|
||||
return Err(~"invalid file: missing NUL in string_table");
|
||||
|
|
|
|||
|
|
@ -11,11 +11,10 @@
|
|||
/// Implement ncurses-compatible database discovery
|
||||
/// Does not support hashed database, only filesystem!
|
||||
|
||||
use core::prelude::*;
|
||||
use core::{os, str};
|
||||
use core::os::getenv;
|
||||
use core::io::{file_reader, Reader};
|
||||
use path = core::path::Path;
|
||||
use std::{os, str};
|
||||
use std::os::getenv;
|
||||
use std::io::{file_reader, Reader};
|
||||
use path = std::path::Path;
|
||||
|
||||
/// Return path to database entry for `term`
|
||||
pub fn get_dbpath_for_term(term: &str) -> Option<~path> {
|
||||
|
|
@ -55,7 +54,7 @@ pub fn get_dbpath_for_term(term: &str) -> Option<~path> {
|
|||
};
|
||||
|
||||
// Look for the terminal in all of the search directories
|
||||
for dirs_to_search.each |p| {
|
||||
for dirs_to_search.iter().advance |p| {
|
||||
let newp = ~p.push_many(&[str::from_char(first_char), term.to_owned()]);
|
||||
if os::path_exists(p) && os::path_exists(newp) {
|
||||
return Some(newp);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::hashmap::HashMap;
|
||||
use std::hashmap::HashMap;
|
||||
|
||||
/// A parsed terminfo entry.
|
||||
pub struct TermInfo {
|
||||
|
|
|
|||
|
|
@ -15,21 +15,26 @@
|
|||
// simplest interface possible for representing and running tests
|
||||
// while providing a base that other test frameworks may build off of.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use getopts;
|
||||
use sort;
|
||||
use stats::Stats;
|
||||
use term;
|
||||
use time::precise_time_ns;
|
||||
|
||||
use core::comm::{stream, SharedChan};
|
||||
use core::either;
|
||||
use core::io;
|
||||
use core::option;
|
||||
use core::result;
|
||||
use core::task;
|
||||
use core::to_str::ToStr;
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use std::comm::{stream, SharedChan};
|
||||
use std::either;
|
||||
use std::io;
|
||||
use std::num;
|
||||
use std::option;
|
||||
use std::rand::RngUtil;
|
||||
use std::rand;
|
||||
use std::result;
|
||||
use std::task;
|
||||
use std::to_str::ToStr;
|
||||
use std::u64;
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
|
||||
|
||||
// The name of a test. By convention this follows the rules for rust
|
||||
|
|
@ -131,7 +136,7 @@ type OptRes = Either<TestOpts, ~str>;
|
|||
|
||||
// Parses command line arguments into test options
|
||||
pub fn parse_opts(args: &[~str]) -> OptRes {
|
||||
let args_ = vec::tail(args);
|
||||
let args_ = args.tail();
|
||||
let opts = ~[getopts::optflag("ignored"),
|
||||
getopts::optflag("test"),
|
||||
getopts::optflag("bench"),
|
||||
|
|
@ -318,33 +323,33 @@ pub fn run_tests_console(opts: &TestOpts,
|
|||
}
|
||||
|
||||
fn write_ok(out: @io::Writer, use_color: bool) {
|
||||
write_pretty(out, "ok", term::color_green, use_color);
|
||||
write_pretty(out, "ok", term::color::green, use_color);
|
||||
}
|
||||
|
||||
fn write_failed(out: @io::Writer, use_color: bool) {
|
||||
write_pretty(out, "FAILED", term::color_red, use_color);
|
||||
write_pretty(out, "FAILED", term::color::red, use_color);
|
||||
}
|
||||
|
||||
fn write_ignored(out: @io::Writer, use_color: bool) {
|
||||
write_pretty(out, "ignored", term::color_yellow, use_color);
|
||||
write_pretty(out, "ignored", term::color::yellow, use_color);
|
||||
}
|
||||
|
||||
fn write_bench(out: @io::Writer, use_color: bool) {
|
||||
write_pretty(out, "bench", term::color_cyan, use_color);
|
||||
write_pretty(out, "bench", term::color::cyan, use_color);
|
||||
}
|
||||
|
||||
fn write_pretty(out: @io::Writer,
|
||||
word: &str,
|
||||
color: u8,
|
||||
color: term::color::Color,
|
||||
use_color: bool) {
|
||||
let t = term::Terminal::new(out);
|
||||
match t {
|
||||
Ok(term) => {
|
||||
if use_color && term.color_supported {
|
||||
if use_color {
|
||||
term.fg(color);
|
||||
}
|
||||
out.write_str(word);
|
||||
if use_color && term.color_supported {
|
||||
if use_color {
|
||||
term.reset();
|
||||
}
|
||||
},
|
||||
|
|
@ -361,7 +366,7 @@ fn print_failures(st: &ConsoleTestState) {
|
|||
failures.push(name.to_str());
|
||||
}
|
||||
sort::tim_sort(failures);
|
||||
for failures.each |name| {
|
||||
for failures.iter().advance |name| {
|
||||
st.out.write_line(fmt!(" %s", name.to_str()));
|
||||
}
|
||||
}
|
||||
|
|
@ -415,7 +420,7 @@ type MonitorMsg = (TestDesc, TestResult);
|
|||
|
||||
fn run_tests(opts: &TestOpts,
|
||||
tests: ~[TestDescAndFn],
|
||||
callback: @fn(e: TestEvent)) {
|
||||
callback: &fn(e: TestEvent)) {
|
||||
|
||||
let filtered_tests = filter_tests(opts, tests);
|
||||
let filtered_descs = filtered_tests.map(|t| copy t.desc);
|
||||
|
|
@ -423,7 +428,7 @@ fn run_tests(opts: &TestOpts,
|
|||
callback(TeFiltered(filtered_descs));
|
||||
|
||||
let (filtered_tests, filtered_benchs) =
|
||||
do vec::partition(filtered_tests) |e| {
|
||||
do filtered_tests.partition |e| {
|
||||
match e.testfn {
|
||||
StaticTestFn(_) | DynTestFn(_) => true,
|
||||
StaticBenchFn(_) | DynBenchFn(_) => false
|
||||
|
|
@ -436,7 +441,7 @@ fn run_tests(opts: &TestOpts,
|
|||
debug!("using %u test tasks", concurrency);
|
||||
|
||||
let mut remaining = filtered_tests;
|
||||
vec::reverse(remaining);
|
||||
remaining.reverse();
|
||||
let mut pending = 0;
|
||||
|
||||
let (p, ch) = stream();
|
||||
|
|
@ -480,7 +485,7 @@ static sched_overcommit : uint = 1;
|
|||
static sched_overcommit : uint = 4u;
|
||||
|
||||
fn get_concurrency() -> uint {
|
||||
use core::rt;
|
||||
use std::rt;
|
||||
let threads = rt::util::default_sched_threads();
|
||||
if threads == 1 { 1 }
|
||||
else { threads * sched_overcommit }
|
||||
|
|
@ -558,7 +563,7 @@ pub fn run_test(force_ignore: bool,
|
|||
fn run_test_inner(desc: TestDesc,
|
||||
monitor_ch: SharedChan<MonitorMsg>,
|
||||
testfn: ~fn()) {
|
||||
let testfn_cell = ::core::cell::Cell::new(testfn);
|
||||
let testfn_cell = ::std::cell::Cell::new(testfn);
|
||||
do task::spawn {
|
||||
let mut result_future = None; // task::future_result(builder);
|
||||
|
||||
|
|
@ -600,153 +605,144 @@ fn calc_result(desc: &TestDesc, task_succeeded: bool) -> TestResult {
|
|||
}
|
||||
}
|
||||
|
||||
pub mod bench {
|
||||
use core::prelude::*;
|
||||
|
||||
use core::num;
|
||||
use core::rand::RngUtil;
|
||||
use core::rand;
|
||||
use core::u64;
|
||||
use core::vec;
|
||||
use stats::Stats;
|
||||
use test::{BenchHarness, BenchSamples};
|
||||
use time::precise_time_ns;
|
||||
|
||||
impl BenchHarness {
|
||||
/// Callback for benchmark functions to run in their body.
|
||||
pub fn iter(&mut self, inner:&fn()) {
|
||||
self.ns_start = precise_time_ns();
|
||||
let k = self.iterations;
|
||||
for u64::range(0, k) |_| {
|
||||
inner();
|
||||
}
|
||||
self.ns_end = precise_time_ns();
|
||||
impl BenchHarness {
|
||||
/// Callback for benchmark functions to run in their body.
|
||||
pub fn iter(&mut self, inner:&fn()) {
|
||||
self.ns_start = precise_time_ns();
|
||||
let k = self.iterations;
|
||||
for u64::range(0, k) |_| {
|
||||
inner();
|
||||
}
|
||||
self.ns_end = precise_time_ns();
|
||||
}
|
||||
|
||||
pub fn ns_elapsed(&mut self) -> u64 {
|
||||
if self.ns_start == 0 || self.ns_end == 0 {
|
||||
0
|
||||
} else {
|
||||
self.ns_end - self.ns_start
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ns_per_iter(&mut self) -> u64 {
|
||||
if self.iterations == 0 {
|
||||
0
|
||||
} else {
|
||||
self.ns_elapsed() / self.iterations
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bench_n(&mut self, n: u64, f: &fn(&mut BenchHarness)) {
|
||||
self.iterations = n;
|
||||
debug!("running benchmark for %u iterations",
|
||||
n as uint);
|
||||
f(self);
|
||||
}
|
||||
|
||||
// This is the Go benchmark algorithm. It produces a single
|
||||
// datapoint and always tries to run for 1s.
|
||||
pub fn go_bench(&mut self, f: &fn(&mut BenchHarness)) {
|
||||
|
||||
// Rounds a number down to the nearest power of 10.
|
||||
fn round_down_10(n: u64) -> u64 {
|
||||
let mut n = n;
|
||||
let mut res = 1;
|
||||
while n > 10 {
|
||||
n = n / 10;
|
||||
res *= 10;
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
// Rounds x up to a number of the form [1eX, 2eX, 5eX].
|
||||
fn round_up(n: u64) -> u64 {
|
||||
let base = round_down_10(n);
|
||||
if n < (2 * base) {
|
||||
2 * base
|
||||
} else if n < (5 * base) {
|
||||
5 * base
|
||||
} else {
|
||||
10 * base
|
||||
}
|
||||
}
|
||||
|
||||
// Initial bench run to get ballpark figure.
|
||||
let mut n = 1_u64;
|
||||
self.bench_n(n, f);
|
||||
|
||||
while n < 1_000_000_000 &&
|
||||
self.ns_elapsed() < 1_000_000_000 {
|
||||
let last = n;
|
||||
|
||||
// Try to estimate iter count for 1s falling back to 1bn
|
||||
// iterations if first run took < 1ns.
|
||||
if self.ns_per_iter() == 0 {
|
||||
n = 1_000_000_000;
|
||||
} else {
|
||||
n = 1_000_000_000 / self.ns_per_iter();
|
||||
}
|
||||
|
||||
n = u64::max(u64::min(n+n/2, 100*last), last+1);
|
||||
n = round_up(n);
|
||||
self.bench_n(n, f);
|
||||
}
|
||||
}
|
||||
|
||||
// This is a more statistics-driven benchmark algorithm.
|
||||
// It stops as quickly as 50ms, so long as the statistical
|
||||
// properties are satisfactory. If those properties are
|
||||
// not met, it may run as long as the Go algorithm.
|
||||
pub fn auto_bench(&mut self, f: &fn(&mut BenchHarness)) -> ~[f64] {
|
||||
|
||||
let mut rng = rand::rng();
|
||||
let mut magnitude = 10;
|
||||
let mut prev_madp = 0.0;
|
||||
|
||||
loop {
|
||||
let n_samples = rng.gen_uint_range(50, 60);
|
||||
let n_iter = rng.gen_uint_range(magnitude,
|
||||
magnitude * 2);
|
||||
|
||||
let samples = do vec::from_fn(n_samples) |_| {
|
||||
self.bench_n(n_iter as u64, f);
|
||||
self.ns_per_iter() as f64
|
||||
};
|
||||
|
||||
// Eliminate outliers
|
||||
let med = samples.median();
|
||||
let mad = samples.median_abs_dev();
|
||||
let samples = do vec::filter(samples) |f| {
|
||||
num::abs(*f - med) <= 3.0 * mad
|
||||
};
|
||||
|
||||
debug!("%u samples, median %f, MAD=%f, %u survived filter",
|
||||
n_samples, med as float, mad as float,
|
||||
samples.len());
|
||||
|
||||
if samples.len() != 0 {
|
||||
// If we have _any_ cluster of signal...
|
||||
let curr_madp = samples.median_abs_dev_pct();
|
||||
if self.ns_elapsed() > 1_000_000 &&
|
||||
(curr_madp < 1.0 ||
|
||||
num::abs(curr_madp - prev_madp) < 0.1) {
|
||||
return samples;
|
||||
}
|
||||
prev_madp = curr_madp;
|
||||
|
||||
if n_iter > 20_000_000 ||
|
||||
self.ns_elapsed() > 20_000_000 {
|
||||
return samples;
|
||||
}
|
||||
}
|
||||
|
||||
magnitude *= 2;
|
||||
}
|
||||
pub fn ns_elapsed(&mut self) -> u64 {
|
||||
if self.ns_start == 0 || self.ns_end == 0 {
|
||||
0
|
||||
} else {
|
||||
self.ns_end - self.ns_start
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ns_per_iter(&mut self) -> u64 {
|
||||
if self.iterations == 0 {
|
||||
0
|
||||
} else {
|
||||
self.ns_elapsed() / self.iterations
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bench_n(&mut self, n: u64, f: &fn(&mut BenchHarness)) {
|
||||
self.iterations = n;
|
||||
debug!("running benchmark for %u iterations",
|
||||
n as uint);
|
||||
f(self);
|
||||
}
|
||||
|
||||
// This is the Go benchmark algorithm. It produces a single
|
||||
// datapoint and always tries to run for 1s.
|
||||
pub fn go_bench(&mut self, f: &fn(&mut BenchHarness)) {
|
||||
|
||||
// Rounds a number down to the nearest power of 10.
|
||||
fn round_down_10(n: u64) -> u64 {
|
||||
let mut n = n;
|
||||
let mut res = 1;
|
||||
while n > 10 {
|
||||
n = n / 10;
|
||||
res *= 10;
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
// Rounds x up to a number of the form [1eX, 2eX, 5eX].
|
||||
fn round_up(n: u64) -> u64 {
|
||||
let base = round_down_10(n);
|
||||
if n < (2 * base) {
|
||||
2 * base
|
||||
} else if n < (5 * base) {
|
||||
5 * base
|
||||
} else {
|
||||
10 * base
|
||||
}
|
||||
}
|
||||
|
||||
// Initial bench run to get ballpark figure.
|
||||
let mut n = 1_u64;
|
||||
self.bench_n(n, |x| f(x));
|
||||
|
||||
while n < 1_000_000_000 &&
|
||||
self.ns_elapsed() < 1_000_000_000 {
|
||||
let last = n;
|
||||
|
||||
// Try to estimate iter count for 1s falling back to 1bn
|
||||
// iterations if first run took < 1ns.
|
||||
if self.ns_per_iter() == 0 {
|
||||
n = 1_000_000_000;
|
||||
} else {
|
||||
n = 1_000_000_000 / self.ns_per_iter();
|
||||
}
|
||||
|
||||
n = u64::max(u64::min(n+n/2, 100*last), last+1);
|
||||
n = round_up(n);
|
||||
self.bench_n(n, |x| f(x));
|
||||
}
|
||||
}
|
||||
|
||||
// This is a more statistics-driven benchmark algorithm.
|
||||
// It stops as quickly as 50ms, so long as the statistical
|
||||
// properties are satisfactory. If those properties are
|
||||
// not met, it may run as long as the Go algorithm.
|
||||
pub fn auto_bench(&mut self, f: &fn(&mut BenchHarness)) -> ~[f64] {
|
||||
|
||||
let mut rng = rand::rng();
|
||||
let mut magnitude = 10;
|
||||
let mut prev_madp = 0.0;
|
||||
|
||||
loop {
|
||||
let n_samples = rng.gen_uint_range(50, 60);
|
||||
let n_iter = rng.gen_uint_range(magnitude,
|
||||
magnitude * 2);
|
||||
|
||||
let samples = do vec::from_fn(n_samples) |_| {
|
||||
self.bench_n(n_iter as u64, |x| f(x));
|
||||
self.ns_per_iter() as f64
|
||||
};
|
||||
|
||||
// Eliminate outliers
|
||||
let med = samples.median();
|
||||
let mad = samples.median_abs_dev();
|
||||
let samples = do vec::filter(samples) |f| {
|
||||
num::abs(*f - med) <= 3.0 * mad
|
||||
};
|
||||
|
||||
debug!("%u samples, median %f, MAD=%f, %u survived filter",
|
||||
n_samples, med as float, mad as float,
|
||||
samples.len());
|
||||
|
||||
if samples.len() != 0 {
|
||||
// If we have _any_ cluster of signal...
|
||||
let curr_madp = samples.median_abs_dev_pct();
|
||||
if self.ns_elapsed() > 1_000_000 &&
|
||||
(curr_madp < 1.0 ||
|
||||
num::abs(curr_madp - prev_madp) < 0.1) {
|
||||
return samples;
|
||||
}
|
||||
prev_madp = curr_madp;
|
||||
|
||||
if n_iter > 20_000_000 ||
|
||||
self.ns_elapsed() > 20_000_000 {
|
||||
return samples;
|
||||
}
|
||||
}
|
||||
|
||||
magnitude *= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod bench {
|
||||
use test::{BenchHarness, BenchSamples};
|
||||
|
||||
pub fn benchmark(f: &fn(&mut BenchHarness)) -> BenchSamples {
|
||||
|
||||
let mut bs = BenchHarness {
|
||||
|
|
@ -775,10 +771,10 @@ mod tests {
|
|||
StaticTestName, DynTestName, DynTestFn};
|
||||
use test::{TestOpts, run_test};
|
||||
|
||||
use core::either;
|
||||
use core::comm::{stream, SharedChan};
|
||||
use core::option;
|
||||
use core::vec;
|
||||
use std::either;
|
||||
use std::comm::{stream, SharedChan};
|
||||
use std::option;
|
||||
use std::vec;
|
||||
|
||||
#[test]
|
||||
pub fn do_not_run_ignored_tests() {
|
||||
|
|
@ -938,7 +934,7 @@ mod tests {
|
|||
{
|
||||
fn testfn() { }
|
||||
let mut tests = ~[];
|
||||
for names.each |name| {
|
||||
for names.iter().advance |name| {
|
||||
let test = TestDescAndFn {
|
||||
desc: TestDesc {
|
||||
name: DynTestName(copy *name),
|
||||
|
|
@ -964,7 +960,7 @@ mod tests {
|
|||
|
||||
let pairs = vec::zip(expected, filtered);
|
||||
|
||||
for pairs.each |p| {
|
||||
for pairs.iter().advance |p| {
|
||||
match *p {
|
||||
(ref a, ref b) => {
|
||||
assert!(*a == b.desc.name.to_str());
|
||||
|
|
|
|||
|
|
@ -10,12 +10,11 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::i32;
|
||||
use core::int;
|
||||
use core::io;
|
||||
use core::str;
|
||||
use std::i32;
|
||||
use std::int;
|
||||
use std::io;
|
||||
use std::str;
|
||||
|
||||
static NSEC_PER_SEC: i32 = 1_000_000_000_i32;
|
||||
|
||||
|
|
@ -849,7 +848,7 @@ priv fn do_strftime(format: &str, tm: &Tm) -> ~str {
|
|||
do io::with_str_reader(format) |rdr| {
|
||||
while !rdr.eof() {
|
||||
match rdr.read_char() {
|
||||
'%' => buf += parse_type(rdr.read_char(), tm),
|
||||
'%' => buf.push_str(parse_type(rdr.read_char(), tm)),
|
||||
ch => buf.push_char(ch)
|
||||
}
|
||||
}
|
||||
|
|
@ -862,11 +861,11 @@ priv fn do_strftime(format: &str, tm: &Tm) -> ~str {
|
|||
mod tests {
|
||||
use time::*;
|
||||
|
||||
use core::float;
|
||||
use core::os;
|
||||
use core::result;
|
||||
use core::result::{Err, Ok};
|
||||
use core::str;
|
||||
use std::float;
|
||||
use std::os;
|
||||
use std::result;
|
||||
use std::result::{Err, Ok};
|
||||
use std::str;
|
||||
|
||||
fn test_get_time() {
|
||||
static some_recent_date: i64 = 1325376000i64; // 2012-01-01T00:00:00Z
|
||||
|
|
@ -1033,7 +1032,7 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
for [
|
||||
let days = [
|
||||
~"Sunday",
|
||||
~"Monday",
|
||||
~"Tuesday",
|
||||
|
|
@ -1041,11 +1040,12 @@ mod tests {
|
|||
~"Thursday",
|
||||
~"Friday",
|
||||
~"Saturday"
|
||||
].each |day| {
|
||||
];
|
||||
for days.iter().advance |day| {
|
||||
assert!(test(*day, "%A"));
|
||||
}
|
||||
|
||||
for [
|
||||
let days = [
|
||||
~"Sun",
|
||||
~"Mon",
|
||||
~"Tue",
|
||||
|
|
@ -1053,11 +1053,12 @@ mod tests {
|
|||
~"Thu",
|
||||
~"Fri",
|
||||
~"Sat"
|
||||
].each |day| {
|
||||
];
|
||||
for days.iter().advance |day| {
|
||||
assert!(test(*day, "%a"));
|
||||
}
|
||||
|
||||
for [
|
||||
let months = [
|
||||
~"January",
|
||||
~"February",
|
||||
~"March",
|
||||
|
|
@ -1070,11 +1071,12 @@ mod tests {
|
|||
~"October",
|
||||
~"November",
|
||||
~"December"
|
||||
].each |day| {
|
||||
];
|
||||
for months.iter().advance |day| {
|
||||
assert!(test(*day, "%B"));
|
||||
}
|
||||
|
||||
for [
|
||||
let months = [
|
||||
~"Jan",
|
||||
~"Feb",
|
||||
~"Mar",
|
||||
|
|
@ -1087,7 +1089,8 @@ mod tests {
|
|||
~"Oct",
|
||||
~"Nov",
|
||||
~"Dec"
|
||||
].each |day| {
|
||||
];
|
||||
for months.iter().advance |day| {
|
||||
assert!(test(*day, "%b"));
|
||||
}
|
||||
|
||||
|
|
@ -1138,6 +1141,9 @@ mod tests {
|
|||
assert!(result::unwrap(strptime("-0800", "%z")).tm_gmtoff ==
|
||||
0);
|
||||
assert!(test("%", "%%"));
|
||||
|
||||
// Test for #7256
|
||||
assert_eq!(strptime("360", "%Y-%m-%d"), Err(~"Invalid year"))
|
||||
}
|
||||
|
||||
fn test_ctime() {
|
||||
|
|
|
|||
|
|
@ -10,18 +10,17 @@
|
|||
|
||||
//! Utilities that leverage libuv's `uv_timer_*` API
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use uv;
|
||||
use uv::iotask;
|
||||
use uv::iotask::IoTask;
|
||||
|
||||
use core::cast::transmute;
|
||||
use core::cast;
|
||||
use core::comm::{stream, Chan, SharedChan, Port, select2i};
|
||||
use core::either;
|
||||
use core::libc::c_void;
|
||||
use core::libc;
|
||||
use std::cast::transmute;
|
||||
use std::cast;
|
||||
use std::comm::{stream, Chan, SharedChan, Port, select2i};
|
||||
use std::either;
|
||||
use std::libc::c_void;
|
||||
use std::libc;
|
||||
|
||||
/**
|
||||
* Wait for timeout period then send provided value over a channel
|
||||
|
|
@ -39,7 +38,7 @@ use core::libc;
|
|||
* * ch - a channel of type T to send a `val` on
|
||||
* * val - a value of type T to send over the provided `ch`
|
||||
*/
|
||||
pub fn delayed_send<T:Owned>(iotask: &IoTask,
|
||||
pub fn delayed_send<T:Send>(iotask: &IoTask,
|
||||
msecs: uint,
|
||||
ch: &Chan<T>,
|
||||
val: T) {
|
||||
|
|
@ -111,7 +110,7 @@ pub fn sleep(iotask: &IoTask, msecs: uint) {
|
|||
*
|
||||
* * `iotask' - `uv::iotask` that the tcp request will run on
|
||||
* * msecs - an mount of time, in milliseconds, to wait to receive
|
||||
* * wait_port - a `core::comm::port<T>` to receive on
|
||||
* * wait_port - a `std::comm::port<T>` to receive on
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
|
|
@ -119,11 +118,12 @@ pub fn sleep(iotask: &IoTask, msecs: uint) {
|
|||
* on the provided port in the allotted timeout period, then the result will
|
||||
* be a `Some(T)`. If not, then `None` will be returned.
|
||||
*/
|
||||
pub fn recv_timeout<T:Copy + Owned>(iotask: &IoTask,
|
||||
pub fn recv_timeout<T:Copy + Send>(iotask: &IoTask,
|
||||
msecs: uint,
|
||||
wait_po: &Port<T>)
|
||||
-> Option<T> {
|
||||
let mut (timeout_po, timeout_ch) = stream::<()>();
|
||||
let (timeout_po, timeout_ch) = stream::<()>();
|
||||
let mut timeout_po = timeout_po;
|
||||
delayed_send(iotask, msecs, &timeout_ch, ());
|
||||
|
||||
// XXX: Workaround due to ports and channels not being &mut. They should
|
||||
|
|
@ -175,16 +175,15 @@ extern fn delayed_send_close_cb(handle: *uv::ll::uv_timer_t) {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use core::prelude::*;
|
||||
|
||||
use timer::*;
|
||||
use uv;
|
||||
|
||||
use core::cell::Cell;
|
||||
use core::pipes::{stream, SharedChan};
|
||||
use core::rand::RngUtil;
|
||||
use core::rand;
|
||||
use core::task;
|
||||
use std::cell::Cell;
|
||||
use std::pipes::{stream, SharedChan};
|
||||
use std::rand::RngUtil;
|
||||
use std::rand;
|
||||
use std::task;
|
||||
|
||||
#[test]
|
||||
fn test_gl_timer_simple_sleep_test() {
|
||||
|
|
@ -217,12 +216,12 @@ mod test {
|
|||
|
||||
for repeat.times {
|
||||
let ch = ch.clone();
|
||||
for spec.each |spec| {
|
||||
for spec.iter().advance |spec| {
|
||||
let (times, maxms) = *spec;
|
||||
let ch = ch.clone();
|
||||
let hl_loop_clone = hl_loop.clone();
|
||||
do task::spawn {
|
||||
use core::rand::*;
|
||||
use std::rand::*;
|
||||
let mut rng = rng();
|
||||
for times.times {
|
||||
sleep(&hl_loop_clone, rng.next() as uint % maxms);
|
||||
|
|
|
|||
|
|
@ -12,10 +12,9 @@
|
|||
//! trees. The only requirement for the types is that the key implements
|
||||
//! `TotalOrd`.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::uint;
|
||||
use core::util::{swap, replace};
|
||||
use std::uint;
|
||||
use std::util::{swap, replace};
|
||||
|
||||
// This is implemented as an AA tree, which is a simplified variation of
|
||||
// a red-black tree where red (horizontal) nodes can only be added
|
||||
|
|
@ -87,10 +86,10 @@ impl<K: Ord + TotalOrd, V> Ord for TreeMap<K, V> {
|
|||
|
||||
impl<K: TotalOrd, V> Container for TreeMap<K, V> {
|
||||
/// Return the number of elements in the map
|
||||
fn len(&const self) -> uint { self.length }
|
||||
fn len(&self) -> uint { self.length }
|
||||
|
||||
/// Return true if the map contains no elements
|
||||
fn is_empty(&const self) -> bool { self.root.is_none() }
|
||||
fn is_empty(&self) -> bool { self.root.is_none() }
|
||||
}
|
||||
|
||||
impl<K: TotalOrd, V> Mutable for TreeMap<K, V> {
|
||||
|
|
@ -107,26 +106,6 @@ impl<K: TotalOrd, V> Map<K, V> for TreeMap<K, V> {
|
|||
self.find(key).is_some()
|
||||
}
|
||||
|
||||
/// Visit all key-value pairs in order
|
||||
fn each<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool {
|
||||
each(&self.root, f)
|
||||
}
|
||||
|
||||
/// Visit all keys in order
|
||||
fn each_key(&self, f: &fn(&K) -> bool) -> bool {
|
||||
self.each(|k, _| f(k))
|
||||
}
|
||||
|
||||
/// Visit all values in order
|
||||
fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool {
|
||||
self.each(|_, v| f(v))
|
||||
}
|
||||
|
||||
/// Iterate over the map and mutate the contained values
|
||||
fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool {
|
||||
mutate_values(&mut self.root, f)
|
||||
}
|
||||
|
||||
/// Return a reference to the value corresponding to the key
|
||||
fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
|
||||
let mut current: &'a Option<~TreeNode<K, V>> = &self.root;
|
||||
|
|
@ -184,6 +163,21 @@ impl<K: TotalOrd, V> TreeMap<K, V> {
|
|||
/// Create an empty TreeMap
|
||||
pub fn new() -> TreeMap<K, V> { TreeMap{root: None, length: 0} }
|
||||
|
||||
/// Visit all keys in order
|
||||
pub fn each_key(&self, f: &fn(&K) -> bool) -> bool {
|
||||
self.iter().advance(|(k, _)| f(k))
|
||||
}
|
||||
|
||||
/// Visit all values in order
|
||||
pub fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool {
|
||||
self.iter().advance(|(_, v)| f(v))
|
||||
}
|
||||
|
||||
/// Iterate over the map and mutate the contained values
|
||||
pub fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool {
|
||||
mutate_values(&mut self.root, f)
|
||||
}
|
||||
|
||||
/// Visit all key-value pairs in reverse order
|
||||
pub fn each_reverse<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool {
|
||||
each_reverse(&self.root, f)
|
||||
|
|
@ -249,22 +243,6 @@ pub struct TreeSet<T> {
|
|||
priv map: TreeMap<T, ()>
|
||||
}
|
||||
|
||||
impl<T: TotalOrd> BaseIter<T> for TreeSet<T> {
|
||||
/// Visit all values in order
|
||||
#[inline]
|
||||
fn each(&self, f: &fn(&T) -> bool) -> bool { self.map.each_key(f) }
|
||||
#[inline]
|
||||
fn size_hint(&self) -> Option<uint> { Some(self.len()) }
|
||||
}
|
||||
|
||||
impl<T: TotalOrd> ReverseIter<T> for TreeSet<T> {
|
||||
/// Visit all values in reverse order
|
||||
#[inline]
|
||||
fn each_reverse(&self, f: &fn(&T) -> bool) -> bool {
|
||||
self.map.each_key_reverse(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Eq + TotalOrd> Eq for TreeSet<T> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &TreeSet<T>) -> bool { self.map == other.map }
|
||||
|
|
@ -286,11 +264,11 @@ impl<T: Ord + TotalOrd> Ord for TreeSet<T> {
|
|||
impl<T: TotalOrd> Container for TreeSet<T> {
|
||||
/// Return the number of elements in the set
|
||||
#[inline]
|
||||
fn len(&const self) -> uint { self.map.len() }
|
||||
fn len(&self) -> uint { self.map.len() }
|
||||
|
||||
/// Return true if the set contains no elements
|
||||
#[inline]
|
||||
fn is_empty(&const self) -> bool { self.map.is_empty() }
|
||||
fn is_empty(&self) -> bool { self.map.is_empty() }
|
||||
}
|
||||
|
||||
impl<T: TotalOrd> Mutable for TreeSet<T> {
|
||||
|
|
@ -499,6 +477,12 @@ impl<T: TotalOrd> TreeSet<T> {
|
|||
pub fn iter<'a>(&'a self) -> TreeSetIterator<'a, T> {
|
||||
TreeSetIterator{iter: self.map.iter()}
|
||||
}
|
||||
|
||||
/// Visit all values in reverse order
|
||||
#[inline]
|
||||
pub fn each_reverse(&self, f: &fn(&T) -> bool) -> bool {
|
||||
self.map.each_key_reverse(f)
|
||||
}
|
||||
}
|
||||
|
||||
/// Lazy forward iterator over a set
|
||||
|
|
@ -526,14 +510,14 @@ impl<K: TotalOrd, V> TreeNode<K, V> {
|
|||
|
||||
fn each<'r, K: TotalOrd, V>(node: &'r Option<~TreeNode<K, V>>,
|
||||
f: &fn(&'r K, &'r V) -> bool) -> bool {
|
||||
node.iter().advance(|x| each(&x.left, f) && f(&x.key, &x.value) &&
|
||||
each(&x.right, f))
|
||||
node.iter().advance(|x| each(&x.left, |k,v| f(k,v)) && f(&x.key, &x.value) &&
|
||||
each(&x.right, |k,v| f(k,v)))
|
||||
}
|
||||
|
||||
fn each_reverse<'r, K: TotalOrd, V>(node: &'r Option<~TreeNode<K, V>>,
|
||||
f: &fn(&'r K, &'r V) -> bool) -> bool {
|
||||
node.iter().advance(|x| each_reverse(&x.right, f) && f(&x.key, &x.value) &&
|
||||
each_reverse(&x.left, f))
|
||||
node.iter().advance(|x| each_reverse(&x.right, |k,v| f(k,v)) && f(&x.key, &x.value) &&
|
||||
each_reverse(&x.left, |k,v| f(k,v)))
|
||||
}
|
||||
|
||||
fn mutate_values<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode<K, V>>,
|
||||
|
|
@ -542,9 +526,9 @@ fn mutate_values<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode<K, V>>,
|
|||
match *node {
|
||||
Some(~TreeNode{key: ref key, value: ref mut value, left: ref mut left,
|
||||
right: ref mut right, _}) => {
|
||||
if !mutate_values(left, f) { return false }
|
||||
if !mutate_values(left, |k,v| f(k,v)) { return false }
|
||||
if !f(key, value) { return false }
|
||||
if !mutate_values(right, f) { return false }
|
||||
if !mutate_values(right, |k,v| f(k,v)) { return false }
|
||||
}
|
||||
None => return false
|
||||
}
|
||||
|
|
@ -704,13 +688,11 @@ fn remove<K: TotalOrd, V>(node: &mut Option<~TreeNode<K, V>>,
|
|||
|
||||
#[cfg(test)]
|
||||
mod test_treemap {
|
||||
use core::prelude::*;
|
||||
|
||||
use super::*;
|
||||
|
||||
use core::rand::RngUtil;
|
||||
use core::rand;
|
||||
use core::vec;
|
||||
use std::rand::RngUtil;
|
||||
use std::rand;
|
||||
|
||||
#[test]
|
||||
fn find_empty() {
|
||||
|
|
@ -781,13 +763,13 @@ mod test_treemap {
|
|||
fn check_equal<K: Eq + TotalOrd, V: Eq>(ctrl: &[(K, V)],
|
||||
map: &TreeMap<K, V>) {
|
||||
assert_eq!(ctrl.is_empty(), map.is_empty());
|
||||
for ctrl.each |x| {
|
||||
for ctrl.iter().advance |x| {
|
||||
let &(k, v) = x;
|
||||
assert!(map.find(&k).unwrap() == &v)
|
||||
}
|
||||
for map.each |map_k, map_v| {
|
||||
for map.iter().advance |(map_k, map_v)| {
|
||||
let mut found = false;
|
||||
for ctrl.each |x| {
|
||||
for ctrl.iter().advance |x| {
|
||||
let &(ctrl_k, ctrl_v) = x;
|
||||
if *map_k == ctrl_k {
|
||||
assert!(*map_v == ctrl_v);
|
||||
|
|
@ -853,7 +835,7 @@ mod test_treemap {
|
|||
for 90.times {
|
||||
let k = rng.gen();
|
||||
let v = rng.gen();
|
||||
if !ctrl.contains(&(k, v)) {
|
||||
if !ctrl.iter().any_(|x| x == &(k, v)) {
|
||||
assert!(map.insert(k, v));
|
||||
ctrl.push((k, v));
|
||||
check_structure(&map);
|
||||
|
|
@ -863,7 +845,7 @@ mod test_treemap {
|
|||
|
||||
for 30.times {
|
||||
let r = rng.gen_uint_range(0, ctrl.len());
|
||||
let (key, _) = vec::remove(&mut ctrl, r);
|
||||
let (key, _) = ctrl.remove(r);
|
||||
assert!(map.remove(&key));
|
||||
check_structure(&map);
|
||||
check_equal(ctrl, &map);
|
||||
|
|
@ -891,7 +873,7 @@ mod test_treemap {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_each() {
|
||||
fn test_iterator() {
|
||||
let mut m = TreeMap::new();
|
||||
|
||||
assert!(m.insert(3, 6));
|
||||
|
|
@ -901,7 +883,7 @@ mod test_treemap {
|
|||
assert!(m.insert(1, 2));
|
||||
|
||||
let mut n = 0;
|
||||
for m.each |k, v| {
|
||||
for m.iter().advance |(k, v)| {
|
||||
assert_eq!(*k, n);
|
||||
assert_eq!(*v, n * 2);
|
||||
n += 1;
|
||||
|
|
@ -1026,7 +1008,6 @@ mod test_treemap {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test_set {
|
||||
use core::prelude::*;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
|
@ -1096,7 +1077,7 @@ mod test_set {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_each() {
|
||||
fn test_iterator() {
|
||||
let mut m = TreeSet::new();
|
||||
|
||||
assert!(m.insert(3));
|
||||
|
|
@ -1106,7 +1087,7 @@ mod test_set {
|
|||
assert!(m.insert(1));
|
||||
|
||||
let mut n = 0;
|
||||
for m.each |x| {
|
||||
for m.iter().advance |x| {
|
||||
println(fmt!("%?", x));
|
||||
assert_eq!(*x, n);
|
||||
n += 1
|
||||
|
|
@ -1135,8 +1116,8 @@ mod test_set {
|
|||
let mut set_a = TreeSet::new();
|
||||
let mut set_b = TreeSet::new();
|
||||
|
||||
for a.each |x| { assert!(set_a.insert(*x)) }
|
||||
for b.each |y| { assert!(set_b.insert(*y)) }
|
||||
for a.iter().advance |x| { assert!(set_a.insert(*x)) }
|
||||
for b.iter().advance |y| { assert!(set_b.insert(*y)) }
|
||||
|
||||
let mut i = 0;
|
||||
for f(&set_a, &set_b) |x| {
|
||||
|
|
|
|||
|
|
@ -10,16 +10,15 @@
|
|||
|
||||
//! A process-wide libuv event loop for library use.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use iotask = uv_iotask;
|
||||
use uv_iotask::{IoTask, spawn_iotask};
|
||||
|
||||
use core::comm::Chan;
|
||||
use core::option::{Some, None};
|
||||
use core::task::task;
|
||||
use core::unstable::global::{global_data_clone_create, global_data_clone};
|
||||
use core::unstable::weak_task::weaken_task;
|
||||
use std::comm::Chan;
|
||||
use std::option::{Some, None};
|
||||
use std::task::task;
|
||||
use std::unstable::global::{global_data_clone_create, global_data_clone};
|
||||
use std::unstable::weak_task::weaken_task;
|
||||
|
||||
/**
|
||||
* Race-free helper to get access to a global task where a libuv
|
||||
|
|
@ -126,11 +125,11 @@ mod test {
|
|||
use uv::ll;
|
||||
use uv_iotask::IoTask;
|
||||
|
||||
use core::libc;
|
||||
use core::task;
|
||||
use core::cast::transmute;
|
||||
use core::libc::c_void;
|
||||
use core::comm::{stream, SharedChan, Chan};
|
||||
use std::libc;
|
||||
use std::task;
|
||||
use std::cast::transmute;
|
||||
use std::libc::c_void;
|
||||
use std::comm::{stream, SharedChan, Chan};
|
||||
|
||||
extern fn simple_timer_close_cb(timer_ptr: *ll::uv_timer_t) {
|
||||
unsafe {
|
||||
|
|
@ -150,9 +149,7 @@ mod test {
|
|||
let hl_loop = &get_gl();
|
||||
do iotask::interact(hl_loop) |_loop_ptr| {
|
||||
debug!(~"closing timer");
|
||||
unsafe {
|
||||
ll::close(timer_ptr, simple_timer_close_cb);
|
||||
}
|
||||
ll::close(timer_ptr, simple_timer_close_cb);
|
||||
debug!(~"about to deref exit_ch_ptr");
|
||||
debug!(~"after msg sent on deref'd exit_ch");
|
||||
};
|
||||
|
|
@ -169,24 +166,22 @@ mod test {
|
|||
let timer_handle = ll::timer_t();
|
||||
let timer_ptr: *ll::uv_timer_t = &timer_handle;
|
||||
do iotask::interact(iotask) |loop_ptr| {
|
||||
unsafe {
|
||||
debug!(~"user code inside interact loop!!!");
|
||||
let init_status = ll::timer_init(loop_ptr, timer_ptr);
|
||||
if(init_status == 0i32) {
|
||||
ll::set_data_for_uv_handle(
|
||||
timer_ptr as *libc::c_void,
|
||||
exit_ch_ptr);
|
||||
let start_status = ll::timer_start(timer_ptr,
|
||||
simple_timer_cb,
|
||||
1u, 0u);
|
||||
if(start_status != 0i32) {
|
||||
fail!("failure on ll::timer_start()");
|
||||
}
|
||||
}
|
||||
else {
|
||||
fail!("failure on ll::timer_init()");
|
||||
debug!(~"user code inside interact loop!!!");
|
||||
let init_status = ll::timer_init(loop_ptr, timer_ptr);
|
||||
if(init_status == 0i32) {
|
||||
ll::set_data_for_uv_handle(
|
||||
timer_ptr as *libc::c_void,
|
||||
exit_ch_ptr);
|
||||
let start_status = ll::timer_start(timer_ptr,
|
||||
simple_timer_cb,
|
||||
1u, 0u);
|
||||
if(start_status != 0i32) {
|
||||
fail!("failure on ll::timer_start()");
|
||||
}
|
||||
}
|
||||
else {
|
||||
fail!("failure on ll::timer_init()");
|
||||
}
|
||||
};
|
||||
exit_po.recv();
|
||||
debug!(
|
||||
|
|
|
|||
|
|
@ -17,14 +17,13 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use ll = uv_ll;
|
||||
|
||||
use core::comm::{stream, Port, Chan, SharedChan};
|
||||
use core::libc::c_void;
|
||||
use core::libc;
|
||||
use core::task;
|
||||
use std::comm::{stream, Port, Chan, SharedChan};
|
||||
use std::libc::c_void;
|
||||
use std::libc;
|
||||
use std::task;
|
||||
|
||||
/// Used to abstract-away direct interaction with a libuv loop.
|
||||
pub struct IoTask {
|
||||
|
|
@ -226,7 +225,7 @@ struct AhData {
|
|||
|
||||
#[cfg(test)]
|
||||
fn impl_uv_iotask_async(iotask: &IoTask) {
|
||||
use core::ptr;
|
||||
use std::ptr;
|
||||
|
||||
let async_handle = ll::async_t();
|
||||
let ah_ptr: *ll::uv_async_t = &async_handle;
|
||||
|
|
|
|||
|
|
@ -33,14 +33,13 @@
|
|||
#[allow(non_camel_case_types)]; // C types
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::libc::{c_void, size_t};
|
||||
use core::libc;
|
||||
use core::ptr::to_unsafe_ptr;
|
||||
use core::ptr;
|
||||
use core::str;
|
||||
use core::vec;
|
||||
use std::libc::{c_void, size_t};
|
||||
use std::libc;
|
||||
use std::ptr::to_unsafe_ptr;
|
||||
use std::ptr;
|
||||
use std::str;
|
||||
use std::vec;
|
||||
|
||||
pub type uv_handle_t = c_void;
|
||||
pub type uv_loop_t = c_void;
|
||||
|
|
@ -362,7 +361,7 @@ pub struct uv_getaddrinfo_t {
|
|||
|
||||
pub mod uv_ll_struct_stubgen {
|
||||
|
||||
use core::ptr;
|
||||
use std::ptr;
|
||||
|
||||
use super::{
|
||||
uv_async_t,
|
||||
|
|
@ -1228,16 +1227,15 @@ pub unsafe fn addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6 {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use core::prelude::*;
|
||||
|
||||
use super::*;
|
||||
|
||||
use core::comm::{SharedChan, stream, GenericChan, GenericPort};
|
||||
use core::libc;
|
||||
use core::str;
|
||||
use core::sys;
|
||||
use core::task;
|
||||
use core::vec;
|
||||
use std::comm::{SharedChan, stream, GenericChan, GenericPort};
|
||||
use std::libc;
|
||||
use std::str;
|
||||
use std::sys;
|
||||
use std::task;
|
||||
use std::vec;
|
||||
|
||||
enum tcp_read_data {
|
||||
tcp_read_eof,
|
||||
|
|
@ -1767,9 +1765,7 @@ mod test {
|
|||
mod impl64 {
|
||||
#[test]
|
||||
fn test_uv_ll_tcp_server_and_request() {
|
||||
unsafe {
|
||||
super::super::impl_uv_tcp_server_and_request();
|
||||
}
|
||||
super::super::impl_uv_tcp_server_and_request();
|
||||
}
|
||||
}
|
||||
#[cfg(target_arch="x86")]
|
||||
|
|
|
|||
|
|
@ -10,24 +10,24 @@
|
|||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use digest::DigestUtil;
|
||||
use json;
|
||||
use sha1;
|
||||
use sha1::Sha1;
|
||||
use serialize::{Encoder, Encodable, Decoder, Decodable};
|
||||
use sort;
|
||||
|
||||
use core::cell::Cell;
|
||||
use core::cmp;
|
||||
use core::comm::{PortOne, oneshot, send_one, recv_one};
|
||||
use core::either::{Either, Left, Right};
|
||||
use core::hashmap::HashMap;
|
||||
use core::io;
|
||||
use core::result;
|
||||
use core::run;
|
||||
use core::task;
|
||||
use core::to_bytes;
|
||||
use core::util::replace;
|
||||
use std::cell::Cell;
|
||||
use std::cmp;
|
||||
use std::comm::{PortOne, oneshot, send_one, recv_one};
|
||||
use std::either::{Either, Left, Right};
|
||||
use std::hashmap::HashMap;
|
||||
use std::io;
|
||||
use std::result;
|
||||
use std::run;
|
||||
use std::task;
|
||||
use std::to_bytes;
|
||||
use std::util::replace;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -106,7 +106,7 @@ struct WorkKey {
|
|||
impl to_bytes::IterBytes for WorkKey {
|
||||
#[inline]
|
||||
fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
|
||||
self.kind.iter_bytes(lsb0, f) && self.name.iter_bytes(lsb0, f)
|
||||
self.kind.iter_bytes(lsb0, |b| f(b)) && self.name.iter_bytes(lsb0, |b| f(b))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +145,7 @@ impl WorkMap {
|
|||
impl<S:Encoder> Encodable<S> for WorkMap {
|
||||
fn encode(&self, s: &mut S) {
|
||||
let mut d = ~[];
|
||||
for self.each |k, v| {
|
||||
for self.iter().advance |(k, v)| {
|
||||
d.push((copy *k, copy *v))
|
||||
}
|
||||
sort::tim_sort(d);
|
||||
|
|
@ -157,7 +157,7 @@ impl<D:Decoder> Decodable<D> for WorkMap {
|
|||
fn decode(d: &mut D) -> WorkMap {
|
||||
let v : ~[(WorkKey,~str)] = Decodable::decode(d);
|
||||
let mut w = WorkMap::new();
|
||||
for v.each |&(k, v)| {
|
||||
for v.iter().advance |&(k, v)| {
|
||||
w.insert(copy k, copy v);
|
||||
}
|
||||
w
|
||||
|
|
@ -248,16 +248,16 @@ fn json_decode<T:Decodable<json::Decoder>>(s: &str) -> T {
|
|||
}
|
||||
|
||||
fn digest<T:Encodable<json::Encoder>>(t: &T) -> ~str {
|
||||
let mut sha = sha1::sha1();
|
||||
sha.input_str(json_encode(t));
|
||||
sha.result_str()
|
||||
let mut sha = ~Sha1::new();
|
||||
(*sha).input_str(json_encode(t));
|
||||
(*sha).result_str()
|
||||
}
|
||||
|
||||
fn digest_file(path: &Path) -> ~str {
|
||||
let mut sha = sha1::sha1();
|
||||
let mut sha = ~Sha1::new();
|
||||
let s = io::read_whole_file_str(path);
|
||||
sha.input_str(*s.get_ref());
|
||||
sha.result_str()
|
||||
(*sha).input_str(*s.get_ref());
|
||||
(*sha).result_str()
|
||||
}
|
||||
|
||||
impl Context {
|
||||
|
|
@ -271,7 +271,7 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn prep<T:Owned +
|
||||
pub fn prep<T:Send +
|
||||
Encodable<json::Encoder> +
|
||||
Decodable<json::Decoder>>(@self, // FIXME(#5121)
|
||||
fn_name:&str,
|
||||
|
|
@ -291,7 +291,7 @@ trait TPrep {
|
|||
fn declare_input(&mut self, kind:&str, name:&str, val:&str);
|
||||
fn is_fresh(&self, cat:&str, kind:&str, name:&str, val:&str) -> bool;
|
||||
fn all_fresh(&self, cat:&str, map:&WorkMap) -> bool;
|
||||
fn exec<T:Owned +
|
||||
fn exec<T:Send +
|
||||
Encodable<json::Encoder> +
|
||||
Decodable<json::Decoder>>( // FIXME(#5121)
|
||||
&self, blk: ~fn(&Exec) -> T) -> Work<T>;
|
||||
|
|
@ -319,7 +319,7 @@ impl TPrep for Prep {
|
|||
}
|
||||
|
||||
fn all_fresh(&self, cat: &str, map: &WorkMap) -> bool {
|
||||
for map.each |k, v| {
|
||||
for map.iter().advance |(k, v)| {
|
||||
if ! self.is_fresh(cat, k.kind, k.name, *v) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -327,7 +327,7 @@ impl TPrep for Prep {
|
|||
return true;
|
||||
}
|
||||
|
||||
fn exec<T:Owned +
|
||||
fn exec<T:Send +
|
||||
Encodable<json::Encoder> +
|
||||
Decodable<json::Decoder>>( // FIXME(#5121)
|
||||
&self, blk: ~fn(&Exec) -> T) -> Work<T> {
|
||||
|
|
@ -364,7 +364,7 @@ impl TPrep for Prep {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Owned +
|
||||
impl<T:Send +
|
||||
Encodable<json::Encoder> +
|
||||
Decodable<json::Decoder>> Work<T> { // FIXME(#5121)
|
||||
pub fn new(p: @mut Prep, e: Either<T,PortOne<(Exec,T)>>) -> Work<T> {
|
||||
|
|
@ -373,7 +373,7 @@ impl<T:Owned +
|
|||
}
|
||||
|
||||
// FIXME (#3724): movable self. This should be in impl Work.
|
||||
fn unwrap<T:Owned +
|
||||
fn unwrap<T:Send +
|
||||
Encodable<json::Encoder> +
|
||||
Decodable<json::Decoder>>( // FIXME(#5121)
|
||||
w: Work<T>) -> T {
|
||||
|
|
@ -402,7 +402,7 @@ fn unwrap<T:Owned +
|
|||
|
||||
//#[test]
|
||||
fn test() {
|
||||
use core::io::WriterUtil;
|
||||
use std::io::WriterUtil;
|
||||
|
||||
let db = @mut Database { db_filename: Path("db.json"),
|
||||
db_cache: HashMap::new(),
|
||||
|
|
|
|||
|
|
@ -13,35 +13,22 @@
|
|||
// FIXME #2238 Make run only accept source that emits an executable
|
||||
|
||||
#[link(name = "rust",
|
||||
vers = "0.7-pre",
|
||||
vers = "0.7",
|
||||
uuid = "4a24da33-5cc8-4037-9352-2cbe9bd9d27c",
|
||||
url = "https://github.com/mozilla/rust/tree/master/src/rust")];
|
||||
|
||||
#[license = "MIT/ASL2"];
|
||||
#[crate_type = "lib"];
|
||||
|
||||
#[no_std];
|
||||
|
||||
extern mod core(name = "std");
|
||||
|
||||
extern mod rustpkg;
|
||||
extern mod rustdoc;
|
||||
extern mod rusti;
|
||||
extern mod rustc;
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::io;
|
||||
use core::os;
|
||||
use core::run;
|
||||
use core::libc::exit;
|
||||
|
||||
// For bootstrapping.
|
||||
mod std {
|
||||
pub use core::os;
|
||||
pub use core::str;
|
||||
pub use core::unstable;
|
||||
}
|
||||
use std::io;
|
||||
use std::os;
|
||||
use std::run;
|
||||
use std::libc::exit;
|
||||
|
||||
enum ValidUsage {
|
||||
Valid(int), Invalid
|
||||
|
|
@ -57,13 +44,13 @@ impl ValidUsage {
|
|||
}
|
||||
|
||||
enum Action<'self> {
|
||||
Call(&'self fn(args: &[~str]) -> ValidUsage),
|
||||
CallMain(&'static str, &'self fn()),
|
||||
Call(&'self fn:Copy(args: &[~str]) -> ValidUsage),
|
||||
CallMain(&'static str, &'self fn:Copy()),
|
||||
}
|
||||
|
||||
enum UsageSource<'self> {
|
||||
UsgStr(&'self str),
|
||||
UsgCall(&'self fn()),
|
||||
UsgCall(&'self fn:Copy()),
|
||||
}
|
||||
|
||||
struct Command<'self> {
|
||||
|
|
@ -135,9 +122,9 @@ fn rustc_help() {
|
|||
}
|
||||
|
||||
fn find_cmd(command_string: &str) -> Option<Command> {
|
||||
do commands.find |command| {
|
||||
do commands.iter().find_ |command| {
|
||||
command.cmd == command_string
|
||||
}
|
||||
}.map_consume(|x| copy *x)
|
||||
}
|
||||
|
||||
fn cmd_help(args: &[~str]) -> ValidUsage {
|
||||
|
|
@ -222,7 +209,7 @@ fn usage() {
|
|||
\n"
|
||||
);
|
||||
|
||||
for commands.each |command| {
|
||||
for commands.iter().advance |command| {
|
||||
let padding = " ".repeat(indent - command.cmd.len());
|
||||
io::println(fmt!(" %s%s%s",
|
||||
command.cmd, padding, command.usage_line));
|
||||
|
|
@ -238,6 +225,12 @@ fn usage() {
|
|||
|
||||
pub fn main() {
|
||||
let os_args = os::args();
|
||||
|
||||
if (os_args.len() > 1 && (os_args[1] == ~"-v" || os_args[1] == ~"--version")) {
|
||||
rustc::version(os_args[0]);
|
||||
unsafe { exit(0); }
|
||||
}
|
||||
|
||||
let args = os_args.tail();
|
||||
|
||||
if !args.is_empty() {
|
||||
|
|
@ -8,9 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
|
||||
|
||||
pub static rc_base_field_refcnt: uint = 0u;
|
||||
|
||||
pub static task_field_refcnt: uint = 0u;
|
||||
|
|
@ -49,20 +46,16 @@ pub static tydesc_field_take_glue: uint = 2u;
|
|||
pub static tydesc_field_drop_glue: uint = 3u;
|
||||
pub static tydesc_field_free_glue: uint = 4u;
|
||||
pub static tydesc_field_visit_glue: uint = 5u;
|
||||
pub static tydesc_field_shape: uint = 6u;
|
||||
pub static tydesc_field_shape_tables: uint = 7u;
|
||||
pub static n_tydesc_fields: uint = 8u;
|
||||
pub static n_tydesc_fields: uint = 6u;
|
||||
|
||||
// The two halves of a closure: code and environment.
|
||||
pub static fn_field_code: uint = 0u;
|
||||
pub static fn_field_box: uint = 1u;
|
||||
|
||||
// The three fields of a trait object/trait instance: vtable, box, and type
|
||||
// description.
|
||||
// The two fields of a trait object/trait instance: vtable and box.
|
||||
// The vtable contains the type descriptor as first element.
|
||||
pub static trt_field_vtable: uint = 0u;
|
||||
pub static trt_field_box: uint = 1u;
|
||||
// This field is only present in unique trait objects, so it comes last.
|
||||
pub static trt_field_tydesc: uint = 2u;
|
||||
|
||||
pub static vec_elt_fill: uint = 0u;
|
||||
|
||||
|
|
@ -73,14 +66,4 @@ pub static vec_elt_elems: uint = 2u;
|
|||
pub static slice_elt_base: uint = 0u;
|
||||
pub static slice_elt_len: uint = 1u;
|
||||
|
||||
pub static worst_case_glue_call_args: uint = 7u;
|
||||
|
||||
pub static abi_version: uint = 1u;
|
||||
|
||||
pub fn memcpy_glue_name() -> ~str { return ~"rust_memcpy_glue"; }
|
||||
|
||||
pub fn bzero_glue_name() -> ~str { return ~"rust_bzero_glue"; }
|
||||
|
||||
pub fn yield_glue_name() -> ~str { return ~"rust_yield_glue"; }
|
||||
|
||||
pub fn no_op_type_glue_name() -> ~str { return ~"rust_no_op_type_glue"; }
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use back::rpath;
|
||||
use driver::session::Session;
|
||||
|
|
@ -19,24 +18,26 @@ use lib;
|
|||
use metadata::common::LinkMeta;
|
||||
use metadata::{encoder, csearch, cstore};
|
||||
use middle::trans::context::CrateContext;
|
||||
use middle::trans::common::gensym_name;
|
||||
use middle::ty;
|
||||
use util::ppaux;
|
||||
|
||||
use core::char;
|
||||
use core::hash::Streaming;
|
||||
use core::hash;
|
||||
use core::libc::{c_int, c_uint};
|
||||
use core::os::consts::{macos, freebsd, linux, android, win32};
|
||||
use core::os;
|
||||
use core::ptr;
|
||||
use core::rt::io::Writer;
|
||||
use core::run;
|
||||
use core::str;
|
||||
use core::vec;
|
||||
use std::char;
|
||||
use std::hash::Streaming;
|
||||
use std::hash;
|
||||
use std::libc::{c_int, c_uint};
|
||||
use std::os::consts::{macos, freebsd, linux, android, win32};
|
||||
use std::os;
|
||||
use std::ptr;
|
||||
use std::rt::io::Writer;
|
||||
use std::run;
|
||||
use std::str;
|
||||
use std::vec;
|
||||
use syntax::ast;
|
||||
use syntax::ast_map::{path, path_mod, path_name};
|
||||
use syntax::attr;
|
||||
use syntax::print::pprust;
|
||||
use syntax::parse::token;
|
||||
|
||||
#[deriving(Eq)]
|
||||
pub enum output_type {
|
||||
|
|
@ -96,7 +97,6 @@ pub fn WriteOutputFile(sess: Session,
|
|||
}
|
||||
|
||||
pub mod jit {
|
||||
use core::prelude::*;
|
||||
|
||||
use back::link::llvm_err;
|
||||
use driver::session::Session;
|
||||
|
|
@ -104,11 +104,11 @@ pub mod jit {
|
|||
use lib::llvm::{ModuleRef, ContextRef};
|
||||
use metadata::cstore;
|
||||
|
||||
use core::cast;
|
||||
use core::ptr;
|
||||
use core::str;
|
||||
use core::sys;
|
||||
use core::unstable::intrinsics;
|
||||
use std::cast;
|
||||
use std::ptr;
|
||||
use std::str;
|
||||
use std::sys;
|
||||
use std::unstable::intrinsics;
|
||||
|
||||
pub fn exec(sess: Session,
|
||||
c: ContextRef,
|
||||
|
|
@ -124,19 +124,18 @@ pub mod jit {
|
|||
// incase the user wants to use an older extra library.
|
||||
|
||||
let cstore = sess.cstore;
|
||||
for cstore::get_used_crate_files(cstore).each |cratepath| {
|
||||
let r = cstore::get_used_crate_files(cstore);
|
||||
for r.iter().advance |cratepath| {
|
||||
let path = cratepath.to_str();
|
||||
|
||||
debug!("linking: %s", path);
|
||||
|
||||
let _: () = str::as_c_str(
|
||||
path,
|
||||
|buf_t| {
|
||||
if !llvm::LLVMRustLoadCrate(manager, buf_t) {
|
||||
llvm_err(sess, ~"Could not link");
|
||||
}
|
||||
debug!("linked: %s", path);
|
||||
});
|
||||
do str::as_c_str(path) |buf_t| {
|
||||
if !llvm::LLVMRustLoadCrate(manager, buf_t) {
|
||||
llvm_err(sess, ~"Could not link");
|
||||
}
|
||||
debug!("linked: %s", path);
|
||||
}
|
||||
}
|
||||
|
||||
// We custom-build a JIT execution engine via some rust wrappers
|
||||
|
|
@ -181,7 +180,6 @@ pub mod jit {
|
|||
}
|
||||
|
||||
pub mod write {
|
||||
use core::prelude::*;
|
||||
|
||||
use back::link::jit;
|
||||
use back::link::{WriteOutputFile, output_type};
|
||||
|
|
@ -197,17 +195,16 @@ pub mod write {
|
|||
|
||||
use back::passes;
|
||||
|
||||
use core::libc::{c_int, c_uint};
|
||||
use core::path::Path;
|
||||
use core::run;
|
||||
use core::str;
|
||||
use std::libc::{c_int, c_uint};
|
||||
use std::path::Path;
|
||||
use std::run;
|
||||
use std::str;
|
||||
|
||||
pub fn is_object_or_assembly_or_exe(ot: output_type) -> bool {
|
||||
if ot == output_type_assembly || ot == output_type_object ||
|
||||
ot == output_type_exe {
|
||||
return true;
|
||||
match ot {
|
||||
output_type_assembly | output_type_object | output_type_exe => true,
|
||||
_ => false
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn run_passes(sess: Session,
|
||||
|
|
@ -290,11 +287,11 @@ pub mod write {
|
|||
session::Aggressive => LLVMOptAggressive
|
||||
};
|
||||
|
||||
let FileType;
|
||||
if output_type == output_type_object ||
|
||||
output_type == output_type_exe {
|
||||
FileType = lib::llvm::ObjectFile;
|
||||
} else { FileType = lib::llvm::AssemblyFile; }
|
||||
let FileType = match output_type {
|
||||
output_type_object | output_type_exe => lib::llvm::ObjectFile,
|
||||
_ => lib::llvm::AssemblyFile
|
||||
};
|
||||
|
||||
// Write optimized bitcode if --save-temps was on.
|
||||
|
||||
if opts.save_temps {
|
||||
|
|
@ -384,11 +381,11 @@ pub mod write {
|
|||
(--android-cross-path)")
|
||||
}
|
||||
};
|
||||
let mut cc_args = ~[];
|
||||
cc_args.push(~"-c");
|
||||
cc_args.push(~"-o");
|
||||
cc_args.push(object.to_str());
|
||||
cc_args.push(assembly.to_str());
|
||||
|
||||
let cc_args = ~[
|
||||
~"-c",
|
||||
~"-o", object.to_str(),
|
||||
assembly.to_str()];
|
||||
|
||||
let prog = run::process_output(cc_prog, cc_args);
|
||||
|
||||
|
|
@ -473,20 +470,20 @@ pub fn build_link_meta(sess: Session,
|
|||
let mut cmh_items = ~[];
|
||||
let linkage_metas = attr::find_linkage_metas(c.node.attrs);
|
||||
attr::require_unique_names(sess.diagnostic(), linkage_metas);
|
||||
for linkage_metas.each |meta| {
|
||||
if "name" == attr::get_meta_item_name(*meta) {
|
||||
match attr::get_meta_item_value_str(*meta) {
|
||||
// Changing attr would avoid the need for the copy
|
||||
// here
|
||||
Some(v) => { name = Some(v); }
|
||||
None => cmh_items.push(*meta)
|
||||
}
|
||||
} else if "vers" == attr::get_meta_item_name(*meta) {
|
||||
match attr::get_meta_item_value_str(*meta) {
|
||||
Some(v) => { vers = Some(v); }
|
||||
None => cmh_items.push(*meta)
|
||||
}
|
||||
} else { cmh_items.push(*meta); }
|
||||
for linkage_metas.iter().advance |meta| {
|
||||
match attr::get_meta_item_value_str(*meta) {
|
||||
Some(value) => {
|
||||
let item_name : &str = attr::get_meta_item_name(*meta);
|
||||
match item_name {
|
||||
// Changing attr would avoid the need for the copy
|
||||
// here
|
||||
"name" => name = Some(value),
|
||||
"vers" => vers = Some(value),
|
||||
_ => cmh_items.push(*meta)
|
||||
}
|
||||
},
|
||||
None => cmh_items.push(*meta)
|
||||
}
|
||||
}
|
||||
|
||||
ProvidedMetas {
|
||||
|
|
@ -521,7 +518,7 @@ pub fn build_link_meta(sess: Session,
|
|||
}
|
||||
ast::meta_list(name, ref mis) => {
|
||||
write_string(symbol_hasher, len_and_str(name));
|
||||
for mis.each |m_| {
|
||||
for mis.iter().advance |m_| {
|
||||
hash(symbol_hasher, m_);
|
||||
}
|
||||
}
|
||||
|
|
@ -529,15 +526,15 @@ pub fn build_link_meta(sess: Session,
|
|||
}
|
||||
|
||||
symbol_hasher.reset();
|
||||
for cmh_items.each |m| {
|
||||
for cmh_items.iter().advance |m| {
|
||||
hash(symbol_hasher, m);
|
||||
}
|
||||
|
||||
for dep_hashes.each |dh| {
|
||||
for dep_hashes.iter().advance |dh| {
|
||||
write_string(symbol_hasher, len_and_str(*dh));
|
||||
}
|
||||
|
||||
// tjc: allocation is unfortunate; need to change core::hash
|
||||
// tjc: allocation is unfortunate; need to change std::hash
|
||||
return truncated_hash_result(symbol_hasher).to_managed();
|
||||
}
|
||||
|
||||
|
|
@ -548,32 +545,32 @@ pub fn build_link_meta(sess: Session,
|
|||
}
|
||||
|
||||
fn crate_meta_name(sess: Session, output: &Path, opt_name: Option<@str>)
|
||||
-> @str {
|
||||
return match opt_name {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
-> @str {
|
||||
match opt_name {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
// to_managed could go away if there was a version of
|
||||
// filestem that returned an @str
|
||||
let name = session::expect(sess,
|
||||
output.filestem(),
|
||||
|| fmt!("output file name `%s` doesn't\
|
||||
appear to have a stem",
|
||||
output.to_str())).to_managed();
|
||||
output.filestem(),
|
||||
|| fmt!("output file name `%s` doesn't\
|
||||
appear to have a stem",
|
||||
output.to_str())).to_managed();
|
||||
warn_missing(sess, "name", name);
|
||||
name
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn crate_meta_vers(sess: Session, opt_vers: Option<@str>) -> @str {
|
||||
return match opt_vers {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
match opt_vers {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
let vers = @"0.0";
|
||||
warn_missing(sess, "vers", vers);
|
||||
vers
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let ProvidedMetas {
|
||||
|
|
@ -618,7 +615,7 @@ pub fn symbol_hash(tcx: ty::ctxt,
|
|||
let mut hash = truncated_hash_result(symbol_hasher);
|
||||
// Prefix with _ so that it never blends into adjacent digits
|
||||
hash.unshift_char('_');
|
||||
// tjc: allocation is unfortunate; need to change core::hash
|
||||
// tjc: allocation is unfortunate; need to change std::hash
|
||||
hash.to_managed()
|
||||
}
|
||||
|
||||
|
|
@ -642,15 +639,15 @@ pub fn sanitize(s: &str) -> ~str {
|
|||
for s.iter().advance |c| {
|
||||
match c {
|
||||
// Escape these with $ sequences
|
||||
'@' => result += "$SP$",
|
||||
'~' => result += "$UP$",
|
||||
'*' => result += "$RP$",
|
||||
'&' => result += "$BP$",
|
||||
'<' => result += "$LT$",
|
||||
'>' => result += "$GT$",
|
||||
'(' => result += "$LP$",
|
||||
')' => result += "$RP$",
|
||||
',' => result += "$C$",
|
||||
'@' => result.push_str("$SP$"),
|
||||
'~' => result.push_str("$UP$"),
|
||||
'*' => result.push_str("$RP$"),
|
||||
'&' => result.push_str("$BP$"),
|
||||
'<' => result.push_str("$LT$"),
|
||||
'>' => result.push_str("$GT$"),
|
||||
'(' => result.push_str("$LP$"),
|
||||
')' => result.push_str("$RP$"),
|
||||
',' => result.push_str("$C$"),
|
||||
|
||||
// '.' doesn't occur in types and functions, so reuse it
|
||||
// for ':'
|
||||
|
|
@ -663,9 +660,10 @@ pub fn sanitize(s: &str) -> ~str {
|
|||
| '_' => result.push_char(c),
|
||||
|
||||
_ => {
|
||||
if c > 'z' && char::is_XID_continue(c) {
|
||||
result.push_char(c);
|
||||
}
|
||||
let mut tstr = ~"";
|
||||
do char::escape_unicode(c) |c| { tstr.push_char(c); }
|
||||
result.push_char('$');
|
||||
result.push_str(tstr.slice_from(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -685,13 +683,15 @@ pub fn mangle(sess: Session, ss: path) -> ~str {
|
|||
|
||||
let mut n = ~"_ZN"; // Begin name-sequence.
|
||||
|
||||
for ss.each |s| {
|
||||
match *s { path_name(s) | path_mod(s) => {
|
||||
let sani = sanitize(sess.str_of(s));
|
||||
n += fmt!("%u%s", sani.len(), sani);
|
||||
} }
|
||||
for ss.iter().advance |s| {
|
||||
match *s {
|
||||
path_name(s) | path_mod(s) => {
|
||||
let sani = sanitize(sess.str_of(s));
|
||||
n.push_str(fmt!("%u%s", sani.len(), sani));
|
||||
}
|
||||
}
|
||||
}
|
||||
n += "E"; // End name-sequence.
|
||||
n.push_char('E'); // End name-sequence.
|
||||
n
|
||||
}
|
||||
|
||||
|
|
@ -699,10 +699,10 @@ pub fn exported_name(sess: Session,
|
|||
path: path,
|
||||
hash: &str,
|
||||
vers: &str) -> ~str {
|
||||
return mangle(sess,
|
||||
vec::append_one(
|
||||
vec::append_one(path, path_name(sess.ident_of(hash))),
|
||||
path_name(sess.ident_of(vers))));
|
||||
mangle(sess,
|
||||
vec::append_one(
|
||||
vec::append_one(path, path_name(sess.ident_of(hash))),
|
||||
path_name(sess.ident_of(vers))))
|
||||
}
|
||||
|
||||
pub fn mangle_exported_name(ccx: &mut CrateContext,
|
||||
|
|
@ -733,22 +733,22 @@ pub fn mangle_internal_name_by_type_and_seq(ccx: &mut CrateContext,
|
|||
return mangle(ccx.sess,
|
||||
~[path_name(ccx.sess.ident_of(s)),
|
||||
path_name(ccx.sess.ident_of(hash)),
|
||||
path_name((ccx.names)(name))]);
|
||||
path_name(gensym_name(name))]);
|
||||
}
|
||||
|
||||
pub fn mangle_internal_name_by_path_and_seq(ccx: &mut CrateContext,
|
||||
path: path,
|
||||
mut path: path,
|
||||
flav: &str) -> ~str {
|
||||
return mangle(ccx.sess,
|
||||
vec::append_one(path, path_name((ccx.names)(flav))));
|
||||
path.push(path_name(gensym_name(flav)));
|
||||
mangle(ccx.sess, path)
|
||||
}
|
||||
|
||||
pub fn mangle_internal_name_by_path(ccx: &mut CrateContext, path: path) -> ~str {
|
||||
return mangle(ccx.sess, path);
|
||||
mangle(ccx.sess, path)
|
||||
}
|
||||
|
||||
pub fn mangle_internal_name_by_seq(ccx: &mut CrateContext, flav: &str) -> ~str {
|
||||
return fmt!("%s_%u", flav, (ccx.names)(flav).name);
|
||||
pub fn mangle_internal_name_by_seq(_ccx: &mut CrateContext, flav: &str) -> ~str {
|
||||
return fmt!("%s_%u", flav, token::gensym(flav));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -776,8 +776,8 @@ pub fn link_binary(sess: Session,
|
|||
// so we add a condition to make it use gcc.
|
||||
let cc_prog: ~str = match sess.opts.linker {
|
||||
Some(ref linker) => copy *linker,
|
||||
None => {
|
||||
if sess.targ_cfg.os == session::os_android {
|
||||
None => match sess.targ_cfg.os {
|
||||
session::os_android =>
|
||||
match &sess.opts.android_cross_path {
|
||||
&Some(ref path) => {
|
||||
fmt!("%s/bin/arm-linux-androideabi-gcc", *path)
|
||||
|
|
@ -786,12 +786,9 @@ pub fn link_binary(sess: Session,
|
|||
sess.fatal("need Android NDK path for linking \
|
||||
(--android-cross-path)")
|
||||
}
|
||||
}
|
||||
} else if sess.targ_cfg.os == session::os_win32 {
|
||||
~"gcc"
|
||||
} else {
|
||||
~"cc"
|
||||
}
|
||||
},
|
||||
session::os_win32 => ~"gcc",
|
||||
_ => ~"cc"
|
||||
}
|
||||
};
|
||||
// The invocations of cc share some flags across platforms
|
||||
|
|
@ -866,22 +863,20 @@ pub fn link_args(sess: Session,
|
|||
|
||||
let mut args = vec::append(~[stage], sess.targ_cfg.target_strs.cc_args);
|
||||
|
||||
args.push(~"-o");
|
||||
args.push(output.to_str());
|
||||
args.push(obj_filename.to_str());
|
||||
args.push_all([
|
||||
~"-o", output.to_str(),
|
||||
obj_filename.to_str()]);
|
||||
|
||||
let lib_cmd;
|
||||
let os = sess.targ_cfg.os;
|
||||
if os == session::os_macos {
|
||||
lib_cmd = ~"-dynamiclib";
|
||||
} else {
|
||||
lib_cmd = ~"-shared";
|
||||
}
|
||||
let lib_cmd = match sess.targ_cfg.os {
|
||||
session::os_macos => ~"-dynamiclib",
|
||||
_ => ~"-shared"
|
||||
};
|
||||
|
||||
// # Crate linking
|
||||
|
||||
let cstore = sess.cstore;
|
||||
for cstore::get_used_crate_files(cstore).each |cratepath| {
|
||||
let r = cstore::get_used_crate_files(cstore);
|
||||
for r.iter().advance |cratepath| {
|
||||
if cratepath.filetype() == Some(~".rlib") {
|
||||
args.push(cratepath.to_str());
|
||||
loop;
|
||||
|
|
@ -893,7 +888,7 @@ pub fn link_args(sess: Session,
|
|||
}
|
||||
|
||||
let ula = cstore::get_used_link_args(cstore);
|
||||
for ula.each |arg| { args.push(arg.to_owned()); }
|
||||
for ula.iter().advance |arg| { args.push(arg.to_owned()); }
|
||||
|
||||
// Add all the link args for external crates.
|
||||
do cstore::iter_crate_data(cstore) |crate_num, _| {
|
||||
|
|
@ -911,13 +906,13 @@ pub fn link_args(sess: Session,
|
|||
// to be found at compile time so it is still entirely up to outside
|
||||
// forces to make sure that library can be found at runtime.
|
||||
|
||||
for sess.opts.addl_lib_search_paths.each |path| {
|
||||
for sess.opts.addl_lib_search_paths.iter().advance |path| {
|
||||
args.push(~"-L" + path.to_str());
|
||||
}
|
||||
|
||||
// The names of the extern libraries
|
||||
let used_libs = cstore::get_used_libraries(cstore);
|
||||
for used_libs.each |l| { args.push(~"-l" + *l); }
|
||||
for used_libs.iter().advance |l| { args.push(~"-l" + *l); }
|
||||
|
||||
if *sess.building_library {
|
||||
args.push(lib_cmd);
|
||||
|
|
|
|||
|
|
@ -8,9 +8,8 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::prelude::*;
|
||||
use core::str;
|
||||
use core::io;
|
||||
use std::str;
|
||||
use std::io;
|
||||
|
||||
use driver::session::{OptLevel, No, Less, Aggressive};
|
||||
use driver::session::{Session};
|
||||
|
|
@ -23,7 +22,7 @@ pub struct PassManager {
|
|||
}
|
||||
|
||||
impl Drop for PassManager {
|
||||
fn finalize(&self) {
|
||||
fn drop(&self) {
|
||||
unsafe {
|
||||
llvm::LLVMDisposePassManager(self.llpm);
|
||||
}
|
||||
|
|
@ -60,94 +59,113 @@ impl PassManager {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn create_standard_passes(level:OptLevel) -> ~[~str] {
|
||||
let mut passes = ~[~"strip-dead-prototypes"];
|
||||
pub fn create_standard_passes(level: OptLevel) -> ~[~str] {
|
||||
let mut passes = ~[];
|
||||
|
||||
if level == No {
|
||||
// mostly identical to clang 3.3, all differences are documented with comments
|
||||
|
||||
if level != No {
|
||||
passes.push(~"targetlibinfo");
|
||||
passes.push(~"no-aa");
|
||||
// "tbaa" omitted, we don't emit clang-style type-based alias analysis information
|
||||
passes.push(~"basicaa");
|
||||
passes.push(~"globalopt");
|
||||
passes.push(~"ipsccp");
|
||||
passes.push(~"deadargelim");
|
||||
passes.push(~"instcombine");
|
||||
passes.push(~"simplifycfg");
|
||||
}
|
||||
|
||||
passes.push(~"basiccg");
|
||||
|
||||
if level != No {
|
||||
passes.push(~"prune-eh");
|
||||
}
|
||||
|
||||
passes.push(~"inline-cost");
|
||||
|
||||
if level == No || level == Less {
|
||||
passes.push(~"always-inline");
|
||||
return passes;
|
||||
} else {
|
||||
passes.push(~"inline");
|
||||
}
|
||||
|
||||
passes.push(~"targetlibinfo");
|
||||
|
||||
passes.push(~"scev-aa");
|
||||
passes.push(~"basicaa");
|
||||
|
||||
passes.push(~"instcombine");
|
||||
passes.push(~"simplifycfg");
|
||||
passes.push(~"scalarrepl-ssa");
|
||||
passes.push(~"early-cse");
|
||||
|
||||
passes.push(~"globalopt");
|
||||
passes.push(~"ipsccp");
|
||||
passes.push(~"deadargelim");
|
||||
passes.push(~"instcombine");
|
||||
passes.push(~"simplifycfg");
|
||||
|
||||
passes.push(~"prune-eh");
|
||||
|
||||
passes.push(~"inline");
|
||||
|
||||
passes.push(~"functionattrs");
|
||||
|
||||
if level == Aggressive {
|
||||
passes.push(~"argpromotion");
|
||||
if level != No {
|
||||
passes.push(~"functionattrs");
|
||||
if level == Aggressive {
|
||||
passes.push(~"argpromotion");
|
||||
}
|
||||
passes.push(~"sroa");
|
||||
passes.push(~"domtree");
|
||||
passes.push(~"early-cse");
|
||||
passes.push(~"simplify-libcalls");
|
||||
passes.push(~"lazy-value-info");
|
||||
passes.push(~"jump-threading");
|
||||
passes.push(~"correlated-propagation");
|
||||
passes.push(~"simplifycfg");
|
||||
passes.push(~"instcombine");
|
||||
passes.push(~"tailcallelim");
|
||||
passes.push(~"simplifycfg");
|
||||
passes.push(~"reassociate");
|
||||
passes.push(~"domtree");
|
||||
passes.push(~"loops");
|
||||
passes.push(~"loop-simplify");
|
||||
passes.push(~"lcssa");
|
||||
passes.push(~"loop-rotate");
|
||||
passes.push(~"licm");
|
||||
passes.push(~"lcssa");
|
||||
passes.push(~"loop-unswitch");
|
||||
passes.push(~"instcombine");
|
||||
passes.push(~"scalar-evolution");
|
||||
passes.push(~"loop-simplify");
|
||||
passes.push(~"lcssa");
|
||||
passes.push(~"indvars");
|
||||
passes.push(~"loop-idiom");
|
||||
passes.push(~"loop-deletion");
|
||||
if level == Aggressive {
|
||||
passes.push(~"loop-simplify");
|
||||
passes.push(~"lcssa");
|
||||
passes.push(~"loop-vectorize");
|
||||
passes.push(~"loop-simplify");
|
||||
passes.push(~"lcssa");
|
||||
passes.push(~"scalar-evolution");
|
||||
passes.push(~"loop-simplify");
|
||||
passes.push(~"lcssa");
|
||||
}
|
||||
if level != Less {
|
||||
passes.push(~"loop-unroll");
|
||||
passes.push(~"memdep");
|
||||
passes.push(~"gvn");
|
||||
}
|
||||
passes.push(~"memdep");
|
||||
passes.push(~"memcpyopt");
|
||||
passes.push(~"sccp");
|
||||
passes.push(~"instcombine");
|
||||
passes.push(~"lazy-value-info");
|
||||
passes.push(~"jump-threading");
|
||||
passes.push(~"correlated-propagation");
|
||||
passes.push(~"domtree");
|
||||
passes.push(~"memdep");
|
||||
passes.push(~"dse");
|
||||
passes.push(~"adce");
|
||||
passes.push(~"simplifycfg");
|
||||
passes.push(~"instcombine");
|
||||
// clang does `strip-dead-prototypes` here, since it does not emit them
|
||||
}
|
||||
|
||||
passes.push(~"scalarrepl-ssa");
|
||||
passes.push(~"early-cse");
|
||||
passes.push(~"simplify-libcalls");
|
||||
passes.push(~"jump-threading");
|
||||
passes.push(~"correlated-propagation");
|
||||
passes.push(~"simplifycfg");
|
||||
passes.push(~"instcombine");
|
||||
|
||||
passes.push(~"tailcallelim");
|
||||
passes.push(~"simplifycfg");
|
||||
passes.push(~"reassociate");
|
||||
passes.push(~"loop-rotate");
|
||||
passes.push(~"licm");
|
||||
|
||||
passes.push(~"lcssa");
|
||||
passes.push(~"loop-unswitch");
|
||||
|
||||
passes.push(~"instcombine");
|
||||
passes.push(~"indvars");
|
||||
passes.push(~"loop-idiom");
|
||||
passes.push(~"loop-deletion");
|
||||
|
||||
if level == Aggressive {
|
||||
passes.push(~"loop-vectorize");
|
||||
}
|
||||
|
||||
passes.push(~"loop-unroll");
|
||||
|
||||
if level != Less {
|
||||
passes.push(~"gvn");
|
||||
}
|
||||
|
||||
passes.push(~"memcpyopt");
|
||||
passes.push(~"sccp");
|
||||
|
||||
passes.push(~"instcombine");
|
||||
passes.push(~"jump-threading");
|
||||
passes.push(~"correlated-propagation");
|
||||
passes.push(~"dse");
|
||||
|
||||
passes.push(~"adce");
|
||||
passes.push(~"simplifycfg");
|
||||
passes.push(~"instsimplify");
|
||||
// rustc emits dead prototypes, so always ask LLVM to strip them
|
||||
passes.push(~"strip-dead-prototypes");
|
||||
|
||||
if level != Less {
|
||||
passes.push(~"globaldce");
|
||||
passes.push(~"constmerge");
|
||||
}
|
||||
|
||||
return passes;
|
||||
passes
|
||||
}
|
||||
|
||||
pub fn populate_pass_manager(sess: Session, pm: &mut PassManager, pass_list:&[~str]) {
|
||||
for pass_list.each |&nm| {
|
||||
for pass_list.iter().advance |&nm| {
|
||||
match create_pass(nm) {
|
||||
Some(p) => pm.add_pass(p),
|
||||
None => sess.warn(fmt!("Unknown pass %s", nm))
|
||||
|
|
@ -172,15 +190,15 @@ pub fn list_passes() {
|
|||
io::println("\nAvailable Passes:");
|
||||
|
||||
io::println("\nAnalysis Passes:");
|
||||
for analysis_passes.each |&(name, desc)| {
|
||||
for analysis_passes.iter().advance |&(name, desc)| {
|
||||
io::println(fmt!(" %-30s -- %s", name, desc));
|
||||
}
|
||||
io::println("\nTransformation Passes:");
|
||||
for transform_passes.each |&(name, desc)| {
|
||||
for transform_passes.iter().advance |&(name, desc)| {
|
||||
io::println(fmt!(" %-30s -- %s", name, desc));
|
||||
}
|
||||
io::println("\nUtility Passes:");
|
||||
for utility_passes.each |&(name, desc)| {
|
||||
for utility_passes.iter().advance |&(name, desc)| {
|
||||
io::println(fmt!(" %-30s -- %s", name, desc));
|
||||
}
|
||||
}
|
||||
|
|
@ -298,7 +316,7 @@ static utility_passes : &'static [(&'static str, &'static str)] = &'static [
|
|||
fn passes_exist() {
|
||||
let mut failed = ~[];
|
||||
unsafe { llvm::LLVMInitializePasses(); }
|
||||
for analysis_passes.each() |&(name,_)| {
|
||||
for analysis_passes.iter().advance |&(name,_)| {
|
||||
let pass = create_pass(name);
|
||||
if !pass.is_some() {
|
||||
failed.push(name);
|
||||
|
|
@ -306,7 +324,7 @@ fn passes_exist() {
|
|||
unsafe { llvm::LLVMDestroyPass(pass.get()) }
|
||||
}
|
||||
}
|
||||
for transform_passes.each() |&(name,_)| {
|
||||
for transform_passes.iter().advance |&(name,_)| {
|
||||
let pass = create_pass(name);
|
||||
if !pass.is_some() {
|
||||
failed.push(name);
|
||||
|
|
@ -314,7 +332,7 @@ fn passes_exist() {
|
|||
unsafe { llvm::LLVMDestroyPass(pass.get()) }
|
||||
}
|
||||
}
|
||||
for utility_passes.each() |&(name,_)| {
|
||||
for utility_passes.iter().advance |&(name,_)| {
|
||||
let pass = create_pass(name);
|
||||
if !pass.is_some() {
|
||||
failed.push(name);
|
||||
|
|
@ -325,7 +343,7 @@ fn passes_exist() {
|
|||
|
||||
if failed.len() > 0 {
|
||||
io::println("Some passes don't exist:");
|
||||
for failed.each |&n| {
|
||||
for failed.iter().advance |&n| {
|
||||
io::println(fmt!(" %s", n));
|
||||
}
|
||||
fail!();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -8,23 +8,19 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use driver::session;
|
||||
use metadata::cstore;
|
||||
use metadata::filesearch;
|
||||
|
||||
use core::hashmap::HashSet;
|
||||
use core::os;
|
||||
use core::uint;
|
||||
use core::util;
|
||||
use core::vec;
|
||||
use std::hashmap::HashSet;
|
||||
use std::os;
|
||||
use std::uint;
|
||||
use std::util;
|
||||
use std::vec;
|
||||
|
||||
fn not_win32(os: session::os) -> bool {
|
||||
match os {
|
||||
session::os_win32 => false,
|
||||
_ => true
|
||||
}
|
||||
os != session::os_win32
|
||||
}
|
||||
|
||||
pub fn get_rpath_flags(sess: session::Session, out_filename: &Path)
|
||||
|
|
@ -56,7 +52,7 @@ fn get_sysroot_absolute_rt_lib(sess: session::Session) -> Path {
|
|||
}
|
||||
|
||||
pub fn rpaths_to_flags(rpaths: &[Path]) -> ~[~str] {
|
||||
vec::map(rpaths, |rpath| fmt!("-Wl,-rpath,%s",rpath.to_str()))
|
||||
rpaths.iter().transform(|rpath| fmt!("-Wl,-rpath,%s",rpath.to_str())).collect()
|
||||
}
|
||||
|
||||
fn get_rpaths(os: session::os,
|
||||
|
|
@ -67,7 +63,7 @@ fn get_rpaths(os: session::os,
|
|||
debug!("sysroot: %s", sysroot.to_str());
|
||||
debug!("output: %s", output.to_str());
|
||||
debug!("libs:");
|
||||
for libs.each |libpath| {
|
||||
for libs.iter().advance |libpath| {
|
||||
debug!(" %s", libpath.to_str());
|
||||
}
|
||||
debug!("target_triple: %s", target_triple);
|
||||
|
|
@ -86,7 +82,7 @@ fn get_rpaths(os: session::os,
|
|||
|
||||
fn log_rpaths(desc: &str, rpaths: &[Path]) {
|
||||
debug!("%s rpaths:", desc);
|
||||
for rpaths.each |rpath| {
|
||||
for rpaths.iter().advance |rpath| {
|
||||
debug!(" %s", rpath.to_str());
|
||||
}
|
||||
}
|
||||
|
|
@ -107,22 +103,20 @@ fn get_rpaths(os: session::os,
|
|||
fn get_rpaths_relative_to_output(os: session::os,
|
||||
output: &Path,
|
||||
libs: &[Path]) -> ~[Path] {
|
||||
vec::map(libs, |a| {
|
||||
get_rpath_relative_to_output(os, output, a)
|
||||
})
|
||||
libs.iter().transform(|a| get_rpath_relative_to_output(os, output, a)).collect()
|
||||
}
|
||||
|
||||
pub fn get_rpath_relative_to_output(os: session::os,
|
||||
output: &Path,
|
||||
lib: &Path)
|
||||
-> Path {
|
||||
use core::os;
|
||||
use std::os;
|
||||
|
||||
assert!(not_win32(os));
|
||||
|
||||
// Mac doesn't appear to support $ORIGIN
|
||||
let prefix = match os {
|
||||
session::os_android |session::os_linux | session::os_freebsd
|
||||
session::os_android | session::os_linux | session::os_freebsd
|
||||
=> "$ORIGIN",
|
||||
session::os_macos => "@executable_path",
|
||||
session::os_win32 => util::unreachable()
|
||||
|
|
@ -157,17 +151,17 @@ pub fn get_relative_to(abs1: &Path, abs2: &Path) -> Path {
|
|||
let mut path = ~[];
|
||||
for uint::range(start_idx, len1 - 1) |_i| { path.push(~".."); };
|
||||
|
||||
path.push_all(vec::slice(split2, start_idx, len2 - 1));
|
||||
path.push_all(split2.slice(start_idx, len2 - 1));
|
||||
|
||||
if !path.is_empty() {
|
||||
return Path("").push_many(path);
|
||||
return if !path.is_empty() {
|
||||
Path("").push_many(path)
|
||||
} else {
|
||||
return Path(".");
|
||||
Path(".")
|
||||
}
|
||||
}
|
||||
|
||||
fn get_absolute_rpaths(libs: &[Path]) -> ~[Path] {
|
||||
vec::map(libs, |a| get_absolute_rpath(a) )
|
||||
libs.iter().transform(|a| get_absolute_rpath(a)).collect()
|
||||
}
|
||||
|
||||
pub fn get_absolute_rpath(lib: &Path) -> Path {
|
||||
|
|
@ -188,7 +182,7 @@ pub fn get_install_prefix_rpath(target_triple: &str) -> Path {
|
|||
pub fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] {
|
||||
let mut set = HashSet::new();
|
||||
let mut minimized = ~[];
|
||||
for rpaths.each |rpath| {
|
||||
for rpaths.iter().advance |rpath| {
|
||||
if set.insert(rpath.to_str()) {
|
||||
minimized.push(copy *rpath);
|
||||
}
|
||||
|
|
@ -198,8 +192,7 @@ pub fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] {
|
|||
|
||||
#[cfg(unix, test)]
|
||||
mod test {
|
||||
use core::prelude::*;
|
||||
use core::os;
|
||||
use std::os;
|
||||
|
||||
// FIXME(#2119): the outer attribute should be #[cfg(unix, test)], then
|
||||
// these redundant #[cfg(test)] blocks can be removed
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@
|
|||
|
||||
use driver::session;
|
||||
use middle::trans::base;
|
||||
use middle::trans::common::{T_fn, T_i8, T_i32, T_int, T_ptr, T_void};
|
||||
use lib::llvm::{ModuleRef, ValueRef, TypeRef};
|
||||
use middle::trans::type_::Type;
|
||||
use lib::llvm::{ModuleRef, ValueRef};
|
||||
|
||||
pub struct Upcalls {
|
||||
trace: ValueRef,
|
||||
|
|
@ -22,40 +22,35 @@ pub struct Upcalls {
|
|||
reset_stack_limit: ValueRef
|
||||
}
|
||||
|
||||
pub fn declare_upcalls(targ_cfg: @session::config,
|
||||
llmod: ModuleRef) -> @Upcalls {
|
||||
fn decl(llmod: ModuleRef, prefix: ~str, name: ~str,
|
||||
tys: ~[TypeRef], rv: TypeRef) ->
|
||||
ValueRef {
|
||||
let arg_tys = tys.map(|t| *t);
|
||||
let fn_ty = T_fn(arg_tys, rv);
|
||||
return base::decl_cdecl_fn(llmod, prefix + name, fn_ty);
|
||||
}
|
||||
fn nothrow(f: ValueRef) -> ValueRef {
|
||||
base::set_no_unwind(f); f
|
||||
}
|
||||
let d: &fn(a: ~str, b: ~[TypeRef], c: TypeRef) -> ValueRef =
|
||||
|a,b,c| decl(llmod, ~"upcall_", a, b, c);
|
||||
let dv: &fn(a: ~str, b: ~[TypeRef]) -> ValueRef =
|
||||
|a,b| decl(llmod, ~"upcall_", a, b, T_void());
|
||||
macro_rules! upcall (
|
||||
(fn $name:ident($($arg:expr),+) -> $ret:expr) => ({
|
||||
let fn_ty = Type::func([ $($arg),* ], &$ret);
|
||||
base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty)
|
||||
});
|
||||
(nothrow fn $name:ident($($arg:expr),+) -> $ret:expr) => ({
|
||||
let fn_ty = Type::func([ $($arg),* ], &$ret);
|
||||
let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty);
|
||||
base::set_no_unwind(decl);
|
||||
decl
|
||||
});
|
||||
(nothrow fn $name:ident -> $ret:expr) => ({
|
||||
let fn_ty = Type::func([], &$ret);
|
||||
let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty);
|
||||
base::set_no_unwind(decl);
|
||||
decl
|
||||
})
|
||||
)
|
||||
|
||||
let int_t = T_int(targ_cfg);
|
||||
pub fn declare_upcalls(targ_cfg: @session::config, llmod: ModuleRef) -> @Upcalls {
|
||||
let opaque_ptr = Type::i8().ptr_to();
|
||||
let int_ty = Type::int(targ_cfg.arch);
|
||||
|
||||
@Upcalls {
|
||||
trace: dv(~"trace", ~[T_ptr(T_i8()),
|
||||
T_ptr(T_i8()),
|
||||
int_t]),
|
||||
call_shim_on_c_stack:
|
||||
d(~"call_shim_on_c_stack",
|
||||
// arguments: void *args, void *fn_ptr
|
||||
~[T_ptr(T_i8()), T_ptr(T_i8())],
|
||||
int_t),
|
||||
trace: upcall!(fn trace(opaque_ptr, opaque_ptr, int_ty) -> Type::void()),
|
||||
call_shim_on_c_stack: upcall!(fn call_shim_on_c_stack(opaque_ptr, opaque_ptr) -> int_ty),
|
||||
call_shim_on_rust_stack:
|
||||
d(~"call_shim_on_rust_stack",
|
||||
~[T_ptr(T_i8()), T_ptr(T_i8())], int_t),
|
||||
rust_personality:
|
||||
nothrow(d(~"rust_personality", ~[], T_i32())),
|
||||
reset_stack_limit:
|
||||
nothrow(dv(~"reset_stack_limit", ~[]))
|
||||
upcall!(fn call_shim_on_rust_stack(opaque_ptr, opaque_ptr) -> int_ty),
|
||||
rust_personality: upcall!(nothrow fn rust_personality -> Type::i32()),
|
||||
reset_stack_limit: upcall!(nothrow fn reset_stack_limit -> Type::void())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use back::link;
|
||||
use back::{arm, x86, x86_64, mips};
|
||||
|
|
@ -19,16 +18,16 @@ use front;
|
|||
use lib::llvm::llvm;
|
||||
use metadata::{creader, cstore, filesearch};
|
||||
use metadata;
|
||||
use middle::{trans, freevars, kind, ty, typeck, lint, astencode};
|
||||
use middle::{trans, freevars, kind, ty, typeck, lint, astencode, reachable};
|
||||
use middle;
|
||||
use util::common::time;
|
||||
use util::ppaux;
|
||||
|
||||
use core::hashmap::HashMap;
|
||||
use core::int;
|
||||
use core::io;
|
||||
use core::os;
|
||||
use core::vec;
|
||||
use std::hashmap::HashMap;
|
||||
use std::int;
|
||||
use std::io;
|
||||
use std::os;
|
||||
use std::vec;
|
||||
use extra::getopts::groups::{optopt, optmulti, optflag, optflagopt};
|
||||
use extra::getopts::{opt_present};
|
||||
use extra::getopts;
|
||||
|
|
@ -161,7 +160,7 @@ pub struct compile_upto {
|
|||
#[deriving(Eq)]
|
||||
pub enum compile_phase {
|
||||
cu_parse,
|
||||
cu_expand,
|
||||
cu_expand, // means "it's already expanded"
|
||||
cu_typeck,
|
||||
cu_no_trans,
|
||||
cu_everything,
|
||||
|
|
@ -181,34 +180,40 @@ pub fn compile_rest(sess: Session,
|
|||
|
||||
let time_passes = sess.time_passes();
|
||||
|
||||
let mut crate_opt = curr;
|
||||
let mut crate = curr.unwrap();
|
||||
|
||||
if phases.from == cu_parse || phases.from == cu_everything {
|
||||
|
||||
*sess.building_library = session::building_library(
|
||||
sess.opts.crate_type, crate_opt.unwrap(), sess.opts.test);
|
||||
sess.opts.crate_type, crate, sess.opts.test);
|
||||
|
||||
crate_opt = Some(time(time_passes, ~"expansion", ||
|
||||
// strip before expansion to allow macros to depend on
|
||||
// configuration variables e.g/ in
|
||||
//
|
||||
// #[macro_escape] #[cfg(foo)]
|
||||
// mod bar { macro_rules! baz!(() => {{}}) }
|
||||
//
|
||||
// baz! should not use this definition unless foo is enabled.
|
||||
crate = time(time_passes, ~"configuration 1", ||
|
||||
front::config::strip_unconfigured_items(crate));
|
||||
|
||||
crate = time(time_passes, ~"expansion", ||
|
||||
syntax::ext::expand::expand_crate(sess.parse_sess, copy cfg,
|
||||
crate_opt.unwrap())));
|
||||
crate));
|
||||
|
||||
crate_opt = Some(time(time_passes, ~"configuration", ||
|
||||
front::config::strip_unconfigured_items(crate_opt.unwrap())));
|
||||
// strip again, in case expansion added anything with a #[cfg].
|
||||
crate = time(time_passes, ~"configuration 2", ||
|
||||
front::config::strip_unconfigured_items(crate));
|
||||
|
||||
crate_opt = Some(time(time_passes, ~"maybe building test harness", ||
|
||||
front::test::modify_for_testing(sess, crate_opt.unwrap())));
|
||||
crate = time(time_passes, ~"maybe building test harness", ||
|
||||
front::test::modify_for_testing(sess, crate));
|
||||
}
|
||||
|
||||
if phases.to == cu_expand { return (crate_opt, None); }
|
||||
if phases.to == cu_expand { return (Some(crate), None); }
|
||||
|
||||
assert!(phases.from != cu_no_trans);
|
||||
|
||||
let mut crate = crate_opt.unwrap();
|
||||
|
||||
let (llcx, llmod, link_meta) = {
|
||||
crate = time(time_passes, ~"intrinsic injection", ||
|
||||
front::intrinsic_inject::inject_intrinsic(sess, crate));
|
||||
|
||||
crate = time(time_passes, ~"extra injection", ||
|
||||
front::std_inject::maybe_inject_libstd_ref(sess, crate));
|
||||
|
||||
|
|
@ -293,10 +298,16 @@ pub fn compile_rest(sess: Session,
|
|||
time(time_passes, ~"kind checking", ||
|
||||
kind::check_crate(ty_cx, method_map, crate));
|
||||
|
||||
let reachable_map =
|
||||
time(time_passes, ~"reachability checking", ||
|
||||
reachable::find_reachable(ty_cx, method_map, crate));
|
||||
|
||||
time(time_passes, ~"lint checking", ||
|
||||
lint::check_crate(ty_cx, crate));
|
||||
|
||||
if phases.to == cu_no_trans { return (Some(crate), Some(ty_cx)); }
|
||||
if phases.to == cu_no_trans {
|
||||
return (Some(crate), Some(ty_cx));
|
||||
}
|
||||
|
||||
let maps = astencode::Maps {
|
||||
root_map: root_map,
|
||||
|
|
@ -309,9 +320,13 @@ pub fn compile_rest(sess: Session,
|
|||
|
||||
let outputs = outputs.get_ref();
|
||||
time(time_passes, ~"translation", ||
|
||||
trans::base::trans_crate(sess, crate, ty_cx,
|
||||
trans::base::trans_crate(sess,
|
||||
crate,
|
||||
ty_cx,
|
||||
&outputs.obj_filename,
|
||||
exp_map2, maps))
|
||||
exp_map2,
|
||||
reachable_map,
|
||||
maps))
|
||||
};
|
||||
|
||||
let outputs = outputs.get_ref();
|
||||
|
|
@ -453,7 +468,7 @@ pub fn pretty_print_input(sess: Session, cfg: ast::crate_cfg, input: &input,
|
|||
}
|
||||
|
||||
pub fn get_os(triple: &str) -> Option<session::os> {
|
||||
for os_names.each |&(name, os)| {
|
||||
for os_names.iter().advance |&(name, os)| {
|
||||
if triple.contains(name) { return Some(os) }
|
||||
}
|
||||
None
|
||||
|
|
@ -467,7 +482,7 @@ static os_names : &'static [(&'static str, session::os)] = &'static [
|
|||
("freebsd", session::os_freebsd)];
|
||||
|
||||
pub fn get_arch(triple: &str) -> Option<abi::Architecture> {
|
||||
for architecture_abis.each |&(arch, abi)| {
|
||||
for architecture_abis.iter().advance |&(arch, abi)| {
|
||||
if triple.contains(arch) { return Some(abi) }
|
||||
}
|
||||
None
|
||||
|
|
@ -556,7 +571,7 @@ pub fn build_session_options(binary: @str,
|
|||
lint::deny, lint::forbid];
|
||||
let mut lint_opts = ~[];
|
||||
let lint_dict = lint::get_lint_dict();
|
||||
for lint_levels.each |level| {
|
||||
for lint_levels.iter().advance |level| {
|
||||
let level_name = lint::level_to_str(*level);
|
||||
|
||||
// FIXME: #4318 Instead of to_ascii and to_str_ascii, could use
|
||||
|
|
@ -565,7 +580,7 @@ pub fn build_session_options(binary: @str,
|
|||
let level_short = level_short.to_ascii().to_upper().to_str_ascii();
|
||||
let flags = vec::append(getopts::opt_strs(matches, level_short),
|
||||
getopts::opt_strs(matches, level_name));
|
||||
for flags.each |lint_name| {
|
||||
for flags.iter().advance |lint_name| {
|
||||
let lint_name = lint_name.replace("-", "_");
|
||||
match lint_dict.find_equiv(&lint_name) {
|
||||
None => {
|
||||
|
|
@ -582,9 +597,9 @@ pub fn build_session_options(binary: @str,
|
|||
let mut debugging_opts = 0u;
|
||||
let debug_flags = getopts::opt_strs(matches, "Z");
|
||||
let debug_map = session::debugging_opts_map();
|
||||
for debug_flags.each |debug_flag| {
|
||||
for debug_flags.iter().advance |debug_flag| {
|
||||
let mut this_bit = 0u;
|
||||
for debug_map.each |tuple| {
|
||||
for debug_map.iter().advance |tuple| {
|
||||
let (name, bit) = match *tuple { (ref a, _, b) => (a, b) };
|
||||
if name == debug_flag { this_bit = bit; break; }
|
||||
}
|
||||
|
|
@ -935,7 +950,6 @@ pub fn list_metadata(sess: Session, path: &Path, out: @io::Writer) {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use core::prelude::*;
|
||||
|
||||
use driver::driver::{build_configuration, build_session};
|
||||
use driver::driver::{build_session_options, optgroups, str_input};
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use back::link;
|
||||
use back::target_strs;
|
||||
|
|
@ -29,7 +28,7 @@ use syntax::abi;
|
|||
use syntax::parse::token;
|
||||
use syntax;
|
||||
|
||||
use core::hashmap::HashMap;
|
||||
use std::hashmap::HashMap;
|
||||
|
||||
#[deriving(Eq)]
|
||||
pub enum os { os_win32, os_macos, os_linux, os_android, os_freebsd, }
|
||||
|
|
@ -45,32 +44,33 @@ pub struct config {
|
|||
float_type: float_ty
|
||||
}
|
||||
|
||||
pub static verbose: uint = 1 << 0;
|
||||
pub static time_passes: uint = 1 << 1;
|
||||
pub static count_llvm_insns: uint = 1 << 2;
|
||||
pub static time_llvm_passes: uint = 1 << 3;
|
||||
pub static trans_stats: uint = 1 << 4;
|
||||
pub static asm_comments: uint = 1 << 5;
|
||||
pub static no_verify: uint = 1 << 6;
|
||||
pub static trace: uint = 1 << 7;
|
||||
pub static coherence: uint = 1 << 8;
|
||||
pub static borrowck_stats: uint = 1 << 9;
|
||||
pub static borrowck_note_pure: uint = 1 << 10;
|
||||
pub static borrowck_note_loan: uint = 1 << 11;
|
||||
pub static no_landing_pads: uint = 1 << 12;
|
||||
pub static debug_llvm: uint = 1 << 13;
|
||||
pub static count_type_sizes: uint = 1 << 14;
|
||||
pub static meta_stats: uint = 1 << 15;
|
||||
pub static no_opt: uint = 1 << 16;
|
||||
pub static verbose: uint = 1 << 0;
|
||||
pub static time_passes: uint = 1 << 1;
|
||||
pub static count_llvm_insns: uint = 1 << 2;
|
||||
pub static time_llvm_passes: uint = 1 << 3;
|
||||
pub static trans_stats: uint = 1 << 4;
|
||||
pub static asm_comments: uint = 1 << 5;
|
||||
pub static no_verify: uint = 1 << 6;
|
||||
pub static trace: uint = 1 << 7;
|
||||
pub static coherence: uint = 1 << 8;
|
||||
pub static borrowck_stats: uint = 1 << 9;
|
||||
pub static borrowck_note_pure: uint = 1 << 10;
|
||||
pub static borrowck_note_loan: uint = 1 << 11;
|
||||
pub static no_landing_pads: uint = 1 << 12;
|
||||
pub static debug_llvm: uint = 1 << 13;
|
||||
pub static count_type_sizes: uint = 1 << 14;
|
||||
pub static meta_stats: uint = 1 << 15;
|
||||
pub static no_opt: uint = 1 << 16;
|
||||
pub static no_monomorphic_collapse: uint = 1 << 17;
|
||||
pub static gc: uint = 1 << 18;
|
||||
pub static jit: uint = 1 << 19;
|
||||
pub static debug_info: uint = 1 << 20;
|
||||
pub static extra_debug_info: uint = 1 << 21;
|
||||
pub static statik: uint = 1 << 22;
|
||||
pub static print_link_args: uint = 1 << 23;
|
||||
pub static no_debug_borrows: uint = 1 << 24;
|
||||
pub static lint_llvm : uint = 1 << 25;
|
||||
pub static gc: uint = 1 << 18;
|
||||
pub static jit: uint = 1 << 19;
|
||||
pub static debug_info: uint = 1 << 20;
|
||||
pub static extra_debug_info: uint = 1 << 21;
|
||||
pub static statik: uint = 1 << 22;
|
||||
pub static print_link_args: uint = 1 << 23;
|
||||
pub static no_debug_borrows: uint = 1 << 24;
|
||||
pub static lint_llvm: uint = 1 << 25;
|
||||
pub static once_fns: uint = 1 << 26;
|
||||
|
||||
pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
|
||||
~[(~"verbose", ~"in general, enable more debug printouts", verbose),
|
||||
|
|
@ -112,6 +112,9 @@ pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
|
|||
(~"lint-llvm",
|
||||
~"Run the LLVM lint pass on the pre-optimization IR",
|
||||
lint_llvm),
|
||||
(~"once-fns",
|
||||
~"Allow 'once fn' closures to deinitialize captured variables",
|
||||
once_fns),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -293,6 +296,7 @@ impl Session_ {
|
|||
pub fn debug_borrows(@self) -> bool {
|
||||
self.opts.optimize == No && !self.debugging_opt(no_debug_borrows)
|
||||
}
|
||||
pub fn once_fns(@self) -> bool { self.debugging_opt(once_fns) }
|
||||
|
||||
// pointless function, now...
|
||||
pub fn str_of(@self, id: ast::ident) -> @str {
|
||||
|
|
@ -349,7 +353,7 @@ pub fn expect<T:Copy>(sess: Session,
|
|||
}
|
||||
|
||||
pub fn building_library(req_crate_type: crate_type,
|
||||
crate: @ast::crate,
|
||||
crate: &ast::crate,
|
||||
testing: bool) -> bool {
|
||||
match req_crate_type {
|
||||
bin_crate => false,
|
||||
|
|
@ -403,8 +407,12 @@ mod test {
|
|||
|
||||
fn make_crate(with_bin: bool, with_lib: bool) -> @ast::crate {
|
||||
let mut attrs = ~[];
|
||||
if with_bin { attrs += [make_crate_type_attr(@"bin")]; }
|
||||
if with_lib { attrs += [make_crate_type_attr(@"lib")]; }
|
||||
if with_bin {
|
||||
attrs.push(make_crate_type_attr(@"bin"));
|
||||
}
|
||||
if with_lib {
|
||||
attrs.push(make_crate_type_attr(@"lib"));
|
||||
}
|
||||
@codemap::respan(codemap::dummy_sp(), ast::crate_ {
|
||||
module: ast::_mod { view_items: ~[], items: ~[] },
|
||||
attrs: attrs,
|
||||
|
|
|
|||
|
|
@ -8,10 +8,9 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::option;
|
||||
use core::vec;
|
||||
use std::option;
|
||||
use std::vec;
|
||||
use syntax::{ast, fold, attr};
|
||||
|
||||
type in_cfg_pred = @fn(attrs: ~[ast::attribute]) -> bool;
|
||||
|
|
@ -24,11 +23,11 @@ struct Context {
|
|||
// any items that do not belong in the current configuration
|
||||
pub fn strip_unconfigured_items(crate: @ast::crate) -> @ast::crate {
|
||||
do strip_items(crate) |attrs| {
|
||||
in_cfg(/*bad*/copy crate.node.config, attrs)
|
||||
in_cfg(crate.node.config, attrs)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn strip_items(crate: @ast::crate, in_cfg: in_cfg_pred)
|
||||
pub fn strip_items(crate: &ast::crate, in_cfg: in_cfg_pred)
|
||||
-> @ast::crate {
|
||||
|
||||
let ctxt = @Context { in_cfg: in_cfg };
|
||||
|
|
@ -44,8 +43,7 @@ pub fn strip_items(crate: @ast::crate, in_cfg: in_cfg_pred)
|
|||
.. *fold::default_ast_fold()};
|
||||
|
||||
let fold = fold::make_fold(precursor);
|
||||
let res = @fold.fold_crate(&*crate);
|
||||
return res;
|
||||
@fold.fold_crate(crate)
|
||||
}
|
||||
|
||||
fn filter_item(cx: @Context, item: @ast::item) ->
|
||||
|
|
@ -92,7 +90,7 @@ fn fold_foreign_mod(
|
|||
ast::foreign_mod {
|
||||
sort: nm.sort,
|
||||
abis: nm.abis,
|
||||
view_items: vec::map(filtered_view_items, |x| fld.fold_view_item(*x)),
|
||||
view_items: filtered_view_items.iter().transform(|x| fld.fold_view_item(*x)).collect(),
|
||||
items: filtered_items
|
||||
}
|
||||
}
|
||||
|
|
@ -143,7 +141,7 @@ fn fold_block(
|
|||
let filtered_view_items =
|
||||
filtered_view_items.map(|x| fld.fold_view_item(*x));
|
||||
let mut resulting_stmts = ~[];
|
||||
for filtered_stmts.each |stmt| {
|
||||
for filtered_stmts.iter().advance |stmt| {
|
||||
match fld.fold_stmt(*stmt) {
|
||||
None => {}
|
||||
Some(stmt) => resulting_stmts.push(stmt),
|
||||
|
|
@ -183,12 +181,12 @@ fn trait_method_in_cfg(cx: @Context, meth: &ast::trait_method) -> bool {
|
|||
|
||||
// Determine if an item should be translated in the current crate
|
||||
// configuration based on the item's attributes
|
||||
fn in_cfg(cfg: ast::crate_cfg, attrs: ~[ast::attribute]) -> bool {
|
||||
fn in_cfg(cfg: &[@ast::meta_item], attrs: &[ast::attribute]) -> bool {
|
||||
metas_in_cfg(cfg, attr::attr_metas(attrs))
|
||||
}
|
||||
|
||||
pub fn metas_in_cfg(cfg: ast::crate_cfg,
|
||||
metas: ~[@ast::meta_item]) -> bool {
|
||||
pub fn metas_in_cfg(cfg: &[@ast::meta_item],
|
||||
metas: &[@ast::meta_item]) -> bool {
|
||||
// The "cfg" attributes on the item
|
||||
let cfg_metas = attr::find_meta_items_by_name(metas, "cfg");
|
||||
|
||||
|
|
@ -197,13 +195,13 @@ pub fn metas_in_cfg(cfg: ast::crate_cfg,
|
|||
// which the item is valid
|
||||
let cfg_metas = vec::filter_map(cfg_metas, |i| attr::get_meta_item_list(i));
|
||||
|
||||
if cfg_metas.all(|c| c.is_empty()) { return true; }
|
||||
if cfg_metas.iter().all(|c| c.is_empty()) { return true; }
|
||||
|
||||
cfg_metas.any(|cfg_meta| {
|
||||
cfg_meta.all(|cfg_mi| {
|
||||
cfg_metas.iter().any_(|cfg_meta| {
|
||||
cfg_meta.iter().all(|cfg_mi| {
|
||||
match cfg_mi.node {
|
||||
ast::meta_list(s, ref it) if "not" == s
|
||||
=> it.all(|mi| !attr::contains(cfg, *mi)),
|
||||
=> it.iter().all(|mi| !attr::contains(cfg, *mi)),
|
||||
_ => attr::contains(cfg, *cfg_mi)
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,140 +0,0 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// NB: this file is include_str!'ed into the compiler, re-parsed
|
||||
// and injected into each crate the compiler builds. Keep it small.
|
||||
|
||||
pub mod intrinsic {
|
||||
#[allow(missing_doc)];
|
||||
|
||||
pub use intrinsic::rusti::visit_tydesc;
|
||||
|
||||
// FIXME (#3727): remove this when the interface has settled and the
|
||||
// version in sys is no longer present.
|
||||
pub fn get_tydesc<T>() -> *TyDesc {
|
||||
unsafe {
|
||||
rusti::get_tydesc::<T>() as *TyDesc
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TyDesc {
|
||||
size: uint,
|
||||
align: uint
|
||||
// Remaining fields not listed
|
||||
}
|
||||
|
||||
pub enum Opaque { }
|
||||
|
||||
pub trait TyVisitor {
|
||||
fn visit_bot(&self) -> bool;
|
||||
fn visit_nil(&self) -> bool;
|
||||
fn visit_bool(&self) -> bool;
|
||||
|
||||
fn visit_int(&self) -> bool;
|
||||
fn visit_i8(&self) -> bool;
|
||||
fn visit_i16(&self) -> bool;
|
||||
fn visit_i32(&self) -> bool;
|
||||
fn visit_i64(&self) -> bool;
|
||||
|
||||
fn visit_uint(&self) -> bool;
|
||||
fn visit_u8(&self) -> bool;
|
||||
fn visit_u16(&self) -> bool;
|
||||
fn visit_u32(&self) -> bool;
|
||||
fn visit_u64(&self) -> bool;
|
||||
|
||||
fn visit_float(&self) -> bool;
|
||||
fn visit_f32(&self) -> bool;
|
||||
fn visit_f64(&self) -> bool;
|
||||
|
||||
fn visit_char(&self) -> bool;
|
||||
fn visit_str(&self) -> bool;
|
||||
|
||||
fn visit_estr_box(&self) -> bool;
|
||||
fn visit_estr_uniq(&self) -> bool;
|
||||
fn visit_estr_slice(&self) -> bool;
|
||||
fn visit_estr_fixed(&self, n: uint, sz: uint, align: uint) -> bool;
|
||||
|
||||
fn visit_box(&self, mtbl: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_ptr(&self, mtbl: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_rptr(&self, mtbl: uint, inner: *TyDesc) -> bool;
|
||||
|
||||
fn visit_vec(&self, mtbl: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_evec_box(&self, mtbl: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_evec_fixed(&self, n: uint, sz: uint, align: uint,
|
||||
mtbl: uint, inner: *TyDesc) -> bool;
|
||||
|
||||
fn visit_enter_rec(&self, n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
fn visit_rec_field(&self, i: uint, name: &str,
|
||||
mtbl: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_leave_rec(&self, n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
|
||||
fn visit_enter_class(&self, n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
fn visit_class_field(&self, i: uint, name: &str,
|
||||
mtbl: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_leave_class(&self, n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
|
||||
fn visit_enter_tup(&self, n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
fn visit_tup_field(&self, i: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_leave_tup(&self, n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
|
||||
fn visit_enter_enum(&self, n_variants: uint,
|
||||
get_disr: extern unsafe fn(ptr: *Opaque) -> int,
|
||||
sz: uint, align: uint) -> bool;
|
||||
fn visit_enter_enum_variant(&self, variant: uint,
|
||||
disr_val: int,
|
||||
n_fields: uint,
|
||||
name: &str) -> bool;
|
||||
fn visit_enum_variant_field(&self, i: uint, offset: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_leave_enum_variant(&self, variant: uint,
|
||||
disr_val: int,
|
||||
n_fields: uint,
|
||||
name: &str) -> bool;
|
||||
fn visit_leave_enum(&self, n_variants: uint,
|
||||
get_disr: extern unsafe fn(ptr: *Opaque) -> int,
|
||||
sz: uint, align: uint) -> bool;
|
||||
|
||||
fn visit_enter_fn(&self, purity: uint, proto: uint,
|
||||
n_inputs: uint, retstyle: uint) -> bool;
|
||||
fn visit_fn_input(&self, i: uint, mode: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_fn_output(&self, retstyle: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_leave_fn(&self, purity: uint, proto: uint,
|
||||
n_inputs: uint, retstyle: uint) -> bool;
|
||||
|
||||
fn visit_trait(&self) -> bool;
|
||||
fn visit_var(&self) -> bool;
|
||||
fn visit_var_integral(&self) -> bool;
|
||||
fn visit_param(&self, i: uint) -> bool;
|
||||
fn visit_self(&self) -> bool;
|
||||
fn visit_type(&self) -> bool;
|
||||
fn visit_opaque_box(&self) -> bool;
|
||||
fn visit_constr(&self, inner: *TyDesc) -> bool;
|
||||
fn visit_closure_ptr(&self, ck: uint) -> bool;
|
||||
}
|
||||
|
||||
pub mod rusti {
|
||||
use super::{TyDesc, TyVisitor};
|
||||
|
||||
#[abi = "rust-intrinsic"]
|
||||
pub extern "rust-intrinsic" {
|
||||
pub fn get_tydesc<T>() -> *();
|
||||
pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::vec;
|
||||
use driver::session::Session;
|
||||
use syntax::parse;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::spanned;
|
||||
|
||||
pub fn inject_intrinsic(sess: Session, crate: @ast::crate) -> @ast::crate {
|
||||
let intrinsic_module = include_str!("intrinsic.rs").to_managed();
|
||||
|
||||
let item = parse::parse_item_from_source_str(@"<intrinsic>",
|
||||
intrinsic_module,
|
||||
/*bad*/copy sess.opts.cfg,
|
||||
~[],
|
||||
sess.parse_sess);
|
||||
let item =
|
||||
match item {
|
||||
Some(i) => i,
|
||||
None => {
|
||||
sess.fatal("no item found in intrinsic module");
|
||||
}
|
||||
};
|
||||
|
||||
let items = vec::append(~[item], crate.node.module.items);
|
||||
|
||||
@spanned {
|
||||
node: ast::crate_ {
|
||||
module: ast::_mod {
|
||||
items: items,
|
||||
.. /*bad*/copy crate.node.module
|
||||
},
|
||||
.. /*bad*/copy crate.node
|
||||
},
|
||||
.. /*bad*/copy *crate
|
||||
}
|
||||
}
|
||||
|
|
@ -8,18 +8,17 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use driver::session::Session;
|
||||
|
||||
use core::vec;
|
||||
use std::vec;
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::codemap::dummy_sp;
|
||||
use syntax::codemap;
|
||||
use syntax::fold;
|
||||
|
||||
static STD_VERSION: &'static str = "0.7-pre";
|
||||
static STD_VERSION: &'static str = "0.7";
|
||||
|
||||
pub fn maybe_inject_libstd_ref(sess: Session, crate: @ast::crate)
|
||||
-> @ast::crate {
|
||||
|
|
@ -30,11 +29,11 @@ pub fn maybe_inject_libstd_ref(sess: Session, crate: @ast::crate)
|
|||
}
|
||||
}
|
||||
|
||||
fn use_std(crate: @ast::crate) -> bool {
|
||||
fn use_std(crate: &ast::crate) -> bool {
|
||||
!attr::attrs_contains_name(crate.node.attrs, "no_std")
|
||||
}
|
||||
|
||||
fn inject_libstd_ref(sess: Session, crate: @ast::crate) -> @ast::crate {
|
||||
fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate {
|
||||
fn spanned<T:Copy>(x: T) -> codemap::spanned<T> {
|
||||
codemap::spanned { node: x, span: dummy_sp() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,12 +10,11 @@
|
|||
|
||||
// Code that generates a test runner to run all the tests in a crate
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use driver::session;
|
||||
use front::config;
|
||||
|
||||
use core::vec;
|
||||
use std::vec;
|
||||
use syntax::ast_util::*;
|
||||
use syntax::attr;
|
||||
use syntax::codemap::{dummy_sp, span, ExpandedFrom, CallInfo, NameAndSpan};
|
||||
|
|
@ -92,7 +91,7 @@ fn generate_test_harness(sess: session::Session,
|
|||
return res;
|
||||
}
|
||||
|
||||
fn strip_test_functions(crate: @ast::crate) -> @ast::crate {
|
||||
fn strip_test_functions(crate: &ast::crate) -> @ast::crate {
|
||||
// When not compiling with --test we should not compile the
|
||||
// #[test] functions
|
||||
do config::strip_items(crate) |attrs| {
|
||||
|
|
@ -118,7 +117,7 @@ fn fold_mod(cx: @mut TestCtxt,
|
|||
|
||||
let mod_nomain = ast::_mod {
|
||||
view_items: /*bad*/copy m.view_items,
|
||||
items: vec::map(m.items, |i| nomain(cx, *i)),
|
||||
items: m.items.iter().transform(|i| nomain(cx, *i)).collect(),
|
||||
};
|
||||
|
||||
fold::noop_fold_mod(&mod_nomain, fld)
|
||||
|
|
@ -272,7 +271,7 @@ mod __test {
|
|||
*/
|
||||
|
||||
fn mk_std(cx: &TestCtxt) -> @ast::view_item {
|
||||
let vers = ast::lit_str(@"0.7-pre");
|
||||
let vers = ast::lit_str(@"0.7");
|
||||
let vers = nospan(vers);
|
||||
let mi = ast::meta_name_value(@"vers", vers);
|
||||
let mi = nospan(mi);
|
||||
|
|
@ -386,7 +385,7 @@ fn is_std(cx: &TestCtxt) -> bool {
|
|||
fn mk_test_descs(cx: &TestCtxt) -> @ast::expr {
|
||||
debug!("building test vector from %u tests", cx.testfns.len());
|
||||
let mut descs = ~[];
|
||||
for cx.testfns.each |test| {
|
||||
for cx.testfns.iter().advance |test| {
|
||||
descs.push(mk_test_desc_and_fn_rec(cx, test));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,14 +8,13 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::hashmap::HashMap;
|
||||
use core::libc::{c_uint, c_ushort};
|
||||
use core::option;
|
||||
use core::ptr;
|
||||
use core::str;
|
||||
use core::vec;
|
||||
use std::hashmap::HashMap;
|
||||
use std::libc::{c_uint, c_ushort};
|
||||
use std::option;
|
||||
use std::str;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
pub type Opcode = u32;
|
||||
pub type Bool = c_uint;
|
||||
|
|
@ -268,7 +267,7 @@ pub mod llvm {
|
|||
use super::{SectionIteratorRef, TargetDataRef, TypeKind, TypeRef, UseRef};
|
||||
use super::{ValueRef, PassRef};
|
||||
use super::debuginfo::*;
|
||||
use core::libc::{c_char, c_int, c_longlong, c_ushort, c_uint, c_ulonglong};
|
||||
use std::libc::{c_char, c_int, c_longlong, c_ushort, c_uint, c_ulonglong};
|
||||
|
||||
#[link_args = "-Lrustllvm -lrustllvm"]
|
||||
#[link_name = "rustllvm"]
|
||||
|
|
@ -2121,155 +2120,101 @@ pub fn ConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef {
|
|||
/* Memory-managed object interface to type handles. */
|
||||
|
||||
pub struct TypeNames {
|
||||
type_names: @mut HashMap<TypeRef, @str>,
|
||||
named_types: @mut HashMap<@str, TypeRef>
|
||||
type_names: HashMap<TypeRef, ~str>,
|
||||
named_types: HashMap<~str, TypeRef>
|
||||
}
|
||||
|
||||
pub fn associate_type(tn: @TypeNames, s: @str, t: TypeRef) {
|
||||
assert!(tn.type_names.insert(t, s));
|
||||
assert!(tn.named_types.insert(s, t));
|
||||
}
|
||||
|
||||
pub fn type_has_name(tn: @TypeNames, t: TypeRef) -> Option<@str> {
|
||||
return tn.type_names.find(&t).map_consume(|x| *x);
|
||||
}
|
||||
|
||||
pub fn name_has_type(tn: @TypeNames, s: @str) -> Option<TypeRef> {
|
||||
return tn.named_types.find(&s).map_consume(|x| *x);
|
||||
}
|
||||
|
||||
pub fn mk_type_names() -> @TypeNames {
|
||||
@TypeNames {
|
||||
type_names: @mut HashMap::new(),
|
||||
named_types: @mut HashMap::new()
|
||||
impl TypeNames {
|
||||
pub fn new() -> TypeNames {
|
||||
TypeNames {
|
||||
type_names: HashMap::new(),
|
||||
named_types: HashMap::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_to_str(names: @TypeNames, ty: TypeRef) -> @str {
|
||||
return type_to_str_inner(names, [], ty);
|
||||
}
|
||||
pub fn associate_type(&mut self, s: &str, t: &Type) {
|
||||
assert!(self.type_names.insert(t.to_ref(), s.to_owned()));
|
||||
assert!(self.named_types.insert(s.to_owned(), t.to_ref()));
|
||||
}
|
||||
|
||||
pub fn type_to_str_inner(names: @TypeNames, outer0: &[TypeRef], ty: TypeRef)
|
||||
-> @str {
|
||||
unsafe {
|
||||
match type_has_name(names, ty) {
|
||||
option::Some(n) => return n,
|
||||
_ => {}
|
||||
pub fn find_name<'r>(&'r self, ty: &Type) -> Option<&'r str> {
|
||||
match self.type_names.find(&ty.to_ref()) {
|
||||
Some(a) => Some(a.slice(0, a.len())),
|
||||
None => None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_type(&self, s: &str) -> Option<Type> {
|
||||
self.named_types.find_equiv(&s).map_consume(|x| Type::from_ref(*x))
|
||||
}
|
||||
|
||||
// We have a depth count, because we seem to make infinite types.
|
||||
pub fn type_to_str_depth(&self, ty: Type, depth: int) -> ~str {
|
||||
match self.find_name(&ty) {
|
||||
option::Some(name) => return name.to_owned(),
|
||||
None => ()
|
||||
}
|
||||
|
||||
let outer = vec::append_one(outer0.to_vec(), ty);
|
||||
|
||||
let kind = llvm::LLVMGetTypeKind(ty);
|
||||
|
||||
fn tys_str(names: @TypeNames, outer: &[TypeRef],
|
||||
tys: ~[TypeRef]) -> @str {
|
||||
let mut s = ~"";
|
||||
let mut first: bool = true;
|
||||
for tys.each |t| {
|
||||
if first { first = false; } else { s += ", "; }
|
||||
s += type_to_str_inner(names, outer, *t);
|
||||
}
|
||||
// [Note at-str] FIXME #2543: Could rewrite this without the copy,
|
||||
// but need better @str support.
|
||||
return s.to_managed();
|
||||
if depth == 0 {
|
||||
return ~"###";
|
||||
}
|
||||
|
||||
match kind {
|
||||
Void => return @"Void",
|
||||
Half => return @"Half",
|
||||
Float => return @"Float",
|
||||
Double => return @"Double",
|
||||
X86_FP80 => return @"X86_FP80",
|
||||
FP128 => return @"FP128",
|
||||
PPC_FP128 => return @"PPC_FP128",
|
||||
Label => return @"Label",
|
||||
Integer => {
|
||||
// See [Note at-str]
|
||||
return fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty)
|
||||
as int).to_managed();
|
||||
}
|
||||
Function => {
|
||||
let out_ty: TypeRef = llvm::LLVMGetReturnType(ty);
|
||||
let n_args = llvm::LLVMCountParamTypes(ty) as uint;
|
||||
let args = vec::from_elem(n_args, 0 as TypeRef);
|
||||
llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args));
|
||||
// See [Note at-str]
|
||||
return fmt!("fn(%s) -> %s",
|
||||
tys_str(names, outer, args),
|
||||
type_to_str_inner(names, outer, out_ty)).to_managed();
|
||||
}
|
||||
Struct => {
|
||||
let elts = struct_tys(ty);
|
||||
// See [Note at-str]
|
||||
return fmt!("{%s}", tys_str(names, outer, elts)).to_managed();
|
||||
}
|
||||
Array => {
|
||||
let el_ty = llvm::LLVMGetElementType(ty);
|
||||
// See [Note at-str]
|
||||
return fmt!("[%s@ x %u", type_to_str_inner(names, outer, el_ty),
|
||||
llvm::LLVMGetArrayLength(ty) as uint).to_managed();
|
||||
}
|
||||
Pointer => {
|
||||
let mut i = 0;
|
||||
for outer0.each |tout| {
|
||||
i += 1;
|
||||
if *tout as int == ty as int {
|
||||
let n = outer0.len() - i;
|
||||
// See [Note at-str]
|
||||
return fmt!("*\\%d", n as int).to_managed();
|
||||
unsafe {
|
||||
let kind = ty.kind();
|
||||
|
||||
match kind {
|
||||
Void => ~"Void",
|
||||
Half => ~"Half",
|
||||
Float => ~"Float",
|
||||
Double => ~"Double",
|
||||
X86_FP80 => ~"X86_FP80",
|
||||
FP128 => ~"FP128",
|
||||
PPC_FP128 => ~"PPC_FP128",
|
||||
Label => ~"Label",
|
||||
Vector => ~"Vector",
|
||||
Metadata => ~"Metadata",
|
||||
X86_MMX => ~"X86_MMAX",
|
||||
Integer => {
|
||||
fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty.to_ref()) as int)
|
||||
}
|
||||
}
|
||||
let addrstr = {
|
||||
let addrspace = llvm::LLVMGetPointerAddressSpace(ty) as uint;
|
||||
if addrspace == 0 {
|
||||
~""
|
||||
} else {
|
||||
fmt!("addrspace(%u)", addrspace)
|
||||
Function => {
|
||||
let out_ty = ty.return_type();
|
||||
let args = ty.func_params();
|
||||
let args =
|
||||
args.map(|&ty| self.type_to_str_depth(ty, depth-1)).connect(", ");
|
||||
let out_ty = self.type_to_str_depth(out_ty, depth-1);
|
||||
fmt!("fn(%s) -> %s", args, out_ty)
|
||||
}
|
||||
};
|
||||
// See [Note at-str]
|
||||
return fmt!("%s*%s", addrstr, type_to_str_inner(names,
|
||||
outer,
|
||||
llvm::LLVMGetElementType(ty))).to_managed();
|
||||
}
|
||||
Vector => return @"Vector",
|
||||
Metadata => return @"Metadata",
|
||||
X86_MMX => return @"X86_MMAX",
|
||||
_ => fail!()
|
||||
Struct => {
|
||||
let tys = ty.field_types();
|
||||
let tys = tys.map(|&ty| self.type_to_str_depth(ty, depth-1)).connect(", ");
|
||||
fmt!("{%s}", tys)
|
||||
}
|
||||
Array => {
|
||||
let el_ty = ty.element_type();
|
||||
let el_ty = self.type_to_str_depth(el_ty, depth-1);
|
||||
let len = ty.array_length();
|
||||
fmt!("[%s x %u]", el_ty, len)
|
||||
}
|
||||
Pointer => {
|
||||
let el_ty = ty.element_type();
|
||||
let el_ty = self.type_to_str_depth(el_ty, depth-1);
|
||||
fmt!("*%s", el_ty)
|
||||
}
|
||||
_ => fail!("Unknown Type Kind (%u)", kind as uint)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn float_width(llt: TypeRef) -> uint {
|
||||
unsafe {
|
||||
return match llvm::LLVMGetTypeKind(llt) as int {
|
||||
1 => 32u,
|
||||
2 => 64u,
|
||||
3 => 80u,
|
||||
4 | 5 => 128u,
|
||||
_ => fail!("llvm_float_width called on a non-float type")
|
||||
};
|
||||
pub fn type_to_str(&self, ty: Type) -> ~str {
|
||||
self.type_to_str_depth(ty, 30)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fn_ty_param_tys(fn_ty: TypeRef) -> ~[TypeRef] {
|
||||
unsafe {
|
||||
let args = vec::from_elem(llvm::LLVMCountParamTypes(fn_ty) as uint,
|
||||
0 as TypeRef);
|
||||
llvm::LLVMGetParamTypes(fn_ty, vec::raw::to_ptr(args));
|
||||
return args;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn struct_tys(struct_ty: TypeRef) -> ~[TypeRef] {
|
||||
unsafe {
|
||||
let n_elts = llvm::LLVMCountStructElementTypes(struct_ty) as uint;
|
||||
if n_elts == 0 {
|
||||
return ~[];
|
||||
pub fn val_to_str(&self, val: ValueRef) -> ~str {
|
||||
unsafe {
|
||||
let ty = Type::from_ref(llvm::LLVMTypeOf(val));
|
||||
self.type_to_str(ty)
|
||||
}
|
||||
let mut elts = vec::from_elem(n_elts, ptr::null());
|
||||
llvm::LLVMGetStructElementTypes(struct_ty, &mut elts[0]);
|
||||
return elts;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2281,7 +2226,7 @@ pub struct target_data_res {
|
|||
}
|
||||
|
||||
impl Drop for target_data_res {
|
||||
fn finalize(&self) {
|
||||
fn drop(&self) {
|
||||
unsafe {
|
||||
llvm::LLVMDisposeTargetData(self.TD);
|
||||
}
|
||||
|
|
@ -2318,7 +2263,7 @@ pub struct pass_manager_res {
|
|||
}
|
||||
|
||||
impl Drop for pass_manager_res {
|
||||
fn finalize(&self) {
|
||||
fn drop(&self) {
|
||||
unsafe {
|
||||
llvm::LLVMDisposePassManager(self.PM);
|
||||
}
|
||||
|
|
@ -2354,7 +2299,7 @@ pub struct object_file_res {
|
|||
}
|
||||
|
||||
impl Drop for object_file_res {
|
||||
fn finalize(&self) {
|
||||
fn drop(&self) {
|
||||
unsafe {
|
||||
llvm::LLVMDisposeObjectFile(self.ObjectFile);
|
||||
}
|
||||
|
|
@ -2391,7 +2336,7 @@ pub struct section_iter_res {
|
|||
}
|
||||
|
||||
impl Drop for section_iter_res {
|
||||
fn finalize(&self) {
|
||||
fn drop(&self) {
|
||||
unsafe {
|
||||
llvm::LLVMDisposeSectionIterator(self.SI);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::cast;
|
||||
|
||||
// EBML enum definitions and utils shared by the encoder and decoder
|
||||
|
||||
|
|
@ -111,6 +111,7 @@ pub static tag_items_data_item_reexport_def_id: uint = 0x4e;
|
|||
pub static tag_items_data_item_reexport_name: uint = 0x4f;
|
||||
|
||||
// used to encode crate_ctxt side tables
|
||||
#[deriving(Eq)]
|
||||
pub enum astencode_tag { // Reserves 0x50 -- 0x6f
|
||||
tag_ast = 0x50,
|
||||
|
||||
|
|
@ -136,6 +137,16 @@ pub enum astencode_tag { // Reserves 0x50 -- 0x6f
|
|||
tag_table_moves_map = 0x63,
|
||||
tag_table_capture_map = 0x64
|
||||
}
|
||||
static first_astencode_tag : uint = tag_ast as uint;
|
||||
static last_astencode_tag : uint = tag_table_capture_map as uint;
|
||||
impl astencode_tag {
|
||||
pub fn from_uint(value : uint) -> Option<astencode_tag> {
|
||||
let is_a_tag = first_astencode_tag <= value && value <= last_astencode_tag;
|
||||
if !is_a_tag { None } else {
|
||||
Some(unsafe { cast::transmute(value as int) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub static tag_item_trait_method_sort: uint = 0x70;
|
||||
|
||||
|
|
@ -164,6 +175,10 @@ pub static tag_item_method_tps: uint = 0x7b;
|
|||
pub static tag_item_method_fty: uint = 0x7c;
|
||||
pub static tag_item_method_transformed_self_ty: uint = 0x7d;
|
||||
|
||||
pub static tag_mod_child: uint = 0x7e;
|
||||
pub static tag_misc_info: uint = 0x7f;
|
||||
pub static tag_misc_info_crate_items: uint = 0x80;
|
||||
|
||||
pub struct LinkMeta {
|
||||
name: @str,
|
||||
vers: @str,
|
||||
|
|
|
|||
|
|
@ -10,15 +10,13 @@
|
|||
|
||||
//! Validates all used crates and extern libraries and loads their metadata
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use metadata::cstore;
|
||||
use metadata::decoder;
|
||||
use metadata::filesearch::FileSearch;
|
||||
use metadata::loader;
|
||||
|
||||
use core::hashmap::HashMap;
|
||||
use core::vec;
|
||||
use std::hashmap::HashMap;
|
||||
use syntax::attr;
|
||||
use syntax::codemap::{span, dummy_sp};
|
||||
use syntax::diagnostic::span_handler;
|
||||
|
|
@ -30,7 +28,7 @@ use syntax::ast;
|
|||
// Traverses an AST, reading all the information about use'd crates and extern
|
||||
// libraries necessary for later resolving, typechecking, linking, etc.
|
||||
pub fn read_crates(diag: @span_handler,
|
||||
crate: @ast::crate,
|
||||
crate: &ast::crate,
|
||||
cstore: @mut cstore::CStore,
|
||||
filesearch: @FileSearch,
|
||||
os: loader::os,
|
||||
|
|
@ -53,8 +51,8 @@ pub fn read_crates(diag: @span_handler,
|
|||
.. *visit::default_simple_visitor()});
|
||||
visit_crate(e, crate);
|
||||
visit::visit_crate(crate, ((), v));
|
||||
dump_crates(e.crate_cache);
|
||||
warn_if_multiple_versions(e, diag, e.crate_cache);
|
||||
dump_crates(*e.crate_cache);
|
||||
warn_if_multiple_versions(e, diag, *e.crate_cache);
|
||||
}
|
||||
|
||||
struct cache_entry {
|
||||
|
|
@ -64,9 +62,9 @@ struct cache_entry {
|
|||
metas: @~[@ast::meta_item]
|
||||
}
|
||||
|
||||
fn dump_crates(crate_cache: @mut ~[cache_entry]) {
|
||||
fn dump_crates(crate_cache: &[cache_entry]) {
|
||||
debug!("resolved crates:");
|
||||
for crate_cache.each |entry| {
|
||||
for crate_cache.iter().advance |entry| {
|
||||
debug!("cnum: %?", entry.cnum);
|
||||
debug!("span: %?", entry.span);
|
||||
debug!("hash: %?", entry.hash);
|
||||
|
|
@ -75,33 +73,31 @@ fn dump_crates(crate_cache: @mut ~[cache_entry]) {
|
|||
|
||||
fn warn_if_multiple_versions(e: @mut Env,
|
||||
diag: @span_handler,
|
||||
crate_cache: @mut ~[cache_entry]) {
|
||||
use core::either::*;
|
||||
|
||||
let crate_cache = &mut *crate_cache;
|
||||
crate_cache: &[cache_entry]) {
|
||||
use std::either::*;
|
||||
|
||||
if crate_cache.len() != 0u {
|
||||
let name = loader::crate_name_from_metas(
|
||||
*crate_cache[crate_cache.len() - 1].metas
|
||||
);
|
||||
|
||||
let (matches, non_matches) =
|
||||
partition(crate_cache.map_to_vec(|&entry| {
|
||||
let othername = loader::crate_name_from_metas(
|
||||
copy *entry.metas);
|
||||
if name == othername {
|
||||
Left(entry)
|
||||
} else {
|
||||
Right(entry)
|
||||
}
|
||||
}));
|
||||
let vec: ~[Either<cache_entry, cache_entry>] = crate_cache.iter().transform(|&entry| {
|
||||
let othername = loader::crate_name_from_metas(
|
||||
copy *entry.metas);
|
||||
if name == othername {
|
||||
Left(entry)
|
||||
} else {
|
||||
Right(entry)
|
||||
}
|
||||
}).collect();
|
||||
let (matches, non_matches) = partition(vec);
|
||||
|
||||
assert!(!matches.is_empty());
|
||||
|
||||
if matches.len() != 1u {
|
||||
diag.handler().warn(
|
||||
fmt!("using multiple versions of crate `%s`", name));
|
||||
for matches.each |match_| {
|
||||
for matches.iter().advance |match_| {
|
||||
diag.span_note(match_.span, "used here");
|
||||
let attrs = ~[
|
||||
attr::mk_attr(attr::mk_list_item(
|
||||
|
|
@ -111,7 +107,7 @@ fn warn_if_multiple_versions(e: @mut Env,
|
|||
}
|
||||
}
|
||||
|
||||
warn_if_multiple_versions(e, diag, @mut non_matches);
|
||||
warn_if_multiple_versions(e, diag, non_matches);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,11 +122,11 @@ struct Env {
|
|||
intr: @ident_interner
|
||||
}
|
||||
|
||||
fn visit_crate(e: @mut Env, c: &ast::crate) {
|
||||
fn visit_crate(e: &Env, c: &ast::crate) {
|
||||
let cstore = e.cstore;
|
||||
let link_args = attr::find_attrs_by_name(c.node.attrs, "link_args");
|
||||
|
||||
for link_args.each |a| {
|
||||
for link_args.iter().advance |a| {
|
||||
match attr::get_meta_item_value_str(attr::attr_meta(*a)) {
|
||||
Some(ref linkarg) => {
|
||||
cstore::add_used_link_args(cstore, *linkarg);
|
||||
|
|
@ -152,7 +148,7 @@ fn visit_view_item(e: @mut Env, i: @ast::view_item) {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_item(e: @mut Env, i: @ast::item) {
|
||||
fn visit_item(e: &Env, i: @ast::item) {
|
||||
match i.node {
|
||||
ast::item_foreign_mod(ref fm) => {
|
||||
if fm.abis.is_rust() || fm.abis.is_intrinsic() {
|
||||
|
|
@ -191,7 +187,7 @@ fn visit_item(e: @mut Env, i: @ast::item) {
|
|||
ast::anonymous => { /* do nothing */ }
|
||||
}
|
||||
|
||||
for link_args.each |a| {
|
||||
for link_args.iter().advance |a| {
|
||||
match attr::get_meta_item_value_str(attr::attr_meta(*a)) {
|
||||
Some(linkarg) => {
|
||||
cstore::add_used_link_args(cstore, linkarg);
|
||||
|
|
@ -204,14 +200,13 @@ fn visit_item(e: @mut Env, i: @ast::item) {
|
|||
}
|
||||
}
|
||||
|
||||
fn metas_with(ident: @str, key: @str, metas: ~[@ast::meta_item])
|
||||
fn metas_with(ident: @str, key: @str, mut metas: ~[@ast::meta_item])
|
||||
-> ~[@ast::meta_item] {
|
||||
let name_items = attr::find_meta_items_by_name(metas, key);
|
||||
if name_items.is_empty() {
|
||||
vec::append_one(metas, attr::mk_name_value_item_str(key, ident))
|
||||
} else {
|
||||
metas
|
||||
metas.push(attr::mk_name_value_item_str(key, ident));
|
||||
}
|
||||
metas
|
||||
}
|
||||
|
||||
fn metas_with_ident(ident: @str, metas: ~[@ast::meta_item])
|
||||
|
|
@ -219,11 +214,11 @@ fn metas_with_ident(ident: @str, metas: ~[@ast::meta_item])
|
|||
metas_with(ident, @"name", metas)
|
||||
}
|
||||
|
||||
fn existing_match(e: @mut Env, metas: &[@ast::meta_item], hash: @str)
|
||||
fn existing_match(e: &Env, metas: &[@ast::meta_item], hash: &str)
|
||||
-> Option<int> {
|
||||
for e.crate_cache.each |c| {
|
||||
for e.crate_cache.iter().advance |c| {
|
||||
if loader::metadata_matches(*c.metas, metas)
|
||||
&& (hash.is_empty() || c.hash == hash) {
|
||||
&& (hash.is_empty() || c.hash.as_slice() == hash) {
|
||||
return Some(c.cnum);
|
||||
}
|
||||
}
|
||||
|
|
@ -303,7 +298,8 @@ fn resolve_crate_deps(e: @mut Env, cdata: @~[u8]) -> cstore::cnum_map {
|
|||
// The map from crate numbers in the crate we're resolving to local crate
|
||||
// numbers
|
||||
let mut cnum_map = HashMap::new();
|
||||
for decoder::get_crate_deps(cdata).each |dep| {
|
||||
let r = decoder::get_crate_deps(cdata);
|
||||
for r.iter().advance |dep| {
|
||||
let extrn_cnum = dep.cnum;
|
||||
let cname = dep.name;
|
||||
let cname_str = token::ident_to_str(&dep.name);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
// Searching for information from the cstore
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use metadata::common::*;
|
||||
use metadata::cstore;
|
||||
|
|
@ -18,17 +17,12 @@ use metadata::decoder;
|
|||
use metadata;
|
||||
use middle::{ty, resolve};
|
||||
|
||||
use core::vec;
|
||||
use std::vec;
|
||||
use reader = extra::ebml::reader;
|
||||
use syntax::ast;
|
||||
use syntax::ast_map;
|
||||
use syntax::diagnostic::expect;
|
||||
|
||||
pub struct ProvidedTraitMethodInfo {
|
||||
ty: ty::Method,
|
||||
def_id: ast::def_id
|
||||
}
|
||||
|
||||
pub struct StaticMethodInfo {
|
||||
ident: ast::ident,
|
||||
def_id: ast::def_id,
|
||||
|
|
@ -102,18 +96,14 @@ pub fn get_enum_variants(tcx: ty::ctxt, def: ast::def_id)
|
|||
return decoder::get_enum_variants(cstore.intr, cdata, def.node, tcx)
|
||||
}
|
||||
|
||||
pub fn get_impls_for_mod(cstore: @mut cstore::CStore, def: ast::def_id,
|
||||
name: Option<ast::ident>)
|
||||
-> @~[@resolve::Impl] {
|
||||
let cdata = cstore::get_crate_data(cstore, def.crate);
|
||||
do decoder::get_impls_for_mod(cstore.intr, cdata, def.node, name) |cnum| {
|
||||
cstore::get_crate_data(cstore, cnum)
|
||||
}
|
||||
/// Returns information about the given implementation.
|
||||
pub fn get_impl(cstore: @mut cstore::CStore, impl_def_id: ast::def_id)
|
||||
-> resolve::Impl {
|
||||
let cdata = cstore::get_crate_data(cstore, impl_def_id.crate);
|
||||
decoder::get_impl(cstore.intr, cdata, impl_def_id.node)
|
||||
}
|
||||
|
||||
pub fn get_method(tcx: ty::ctxt,
|
||||
def: ast::def_id) -> ty::Method
|
||||
{
|
||||
pub fn get_method(tcx: ty::ctxt, def: ast::def_id) -> ty::Method {
|
||||
let cdata = cstore::get_crate_data(tcx.cstore, def.crate);
|
||||
decoder::get_method(tcx.cstore.intr, cdata, def.node, tcx)
|
||||
}
|
||||
|
|
@ -134,7 +124,7 @@ pub fn get_trait_method_def_ids(cstore: @mut cstore::CStore,
|
|||
|
||||
pub fn get_provided_trait_methods(tcx: ty::ctxt,
|
||||
def: ast::def_id)
|
||||
-> ~[ProvidedTraitMethodInfo] {
|
||||
-> ~[@ty::Method] {
|
||||
let cstore = tcx.cstore;
|
||||
let cdata = cstore::get_crate_data(cstore, def.crate);
|
||||
decoder::get_provided_trait_methods(cstore.intr, cdata, def.node, tcx)
|
||||
|
|
@ -229,7 +219,7 @@ pub fn get_impl_trait(tcx: ty::ctxt,
|
|||
pub fn get_impl_method(cstore: @mut cstore::CStore,
|
||||
def: ast::def_id,
|
||||
mname: ast::ident)
|
||||
-> ast::def_id {
|
||||
-> Option<ast::def_id> {
|
||||
let cdata = cstore::get_crate_data(cstore, def.crate);
|
||||
decoder::get_impl_method(cstore.intr, cdata, def.node, mname)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,11 @@
|
|||
// The crate store - a central repo for information collected about external
|
||||
// crates and libraries
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use metadata::cstore;
|
||||
use metadata::decoder;
|
||||
|
||||
use core::hashmap::HashMap;
|
||||
use core::vec;
|
||||
use std::hashmap::HashMap;
|
||||
use extra;
|
||||
use syntax::ast;
|
||||
use syntax::parse::token::ident_interner;
|
||||
|
|
@ -86,13 +84,13 @@ pub fn have_crate_data(cstore: &CStore, cnum: ast::crate_num) -> bool {
|
|||
|
||||
pub fn iter_crate_data(cstore: &CStore,
|
||||
i: &fn(ast::crate_num, @crate_metadata)) {
|
||||
for cstore.metas.each |&k, &v| {
|
||||
for cstore.metas.iter().advance |(&k, &v)| {
|
||||
i(k, v);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_used_crate_file(cstore: &mut CStore, lib: &Path) {
|
||||
if !vec::contains(cstore.used_crate_files, lib) {
|
||||
if !cstore.used_crate_files.contains(lib) {
|
||||
cstore.used_crate_files.push(copy *lib);
|
||||
}
|
||||
}
|
||||
|
|
@ -104,7 +102,7 @@ pub fn get_used_crate_files(cstore: &CStore) -> ~[Path] {
|
|||
pub fn add_used_library(cstore: &mut CStore, lib: @str) -> bool {
|
||||
assert!(!lib.is_empty());
|
||||
|
||||
if cstore.used_libraries.contains(&lib) { return false; }
|
||||
if cstore.used_libraries.iter().any_(|x| x == &lib) { return false; }
|
||||
cstore.used_libraries.push(lib);
|
||||
true
|
||||
}
|
||||
|
|
@ -160,7 +158,7 @@ pub fn get_dep_hashes(cstore: &CStore) -> ~[@str] {
|
|||
};
|
||||
|
||||
debug!("sorted:");
|
||||
for sorted.each |x| {
|
||||
for sorted.iter().advance |x| {
|
||||
debug!(" hash[%s]: %s", x.name, x.hash);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,11 +10,10 @@
|
|||
|
||||
// Decoding metadata from a single crate's metadata
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use metadata::cstore::crate_metadata;
|
||||
use metadata::common::*;
|
||||
use metadata::csearch::{ProvidedTraitMethodInfo, StaticMethodInfo};
|
||||
use metadata::csearch::StaticMethodInfo;
|
||||
use metadata::csearch;
|
||||
use metadata::cstore;
|
||||
use metadata::decoder;
|
||||
|
|
@ -23,19 +22,18 @@ use metadata::tydecode::{parse_ty_data, parse_def_id,
|
|||
parse_bare_fn_ty_data, parse_trait_ref_data};
|
||||
use middle::{ty, resolve};
|
||||
|
||||
use core::hash::HashUtil;
|
||||
use core::int;
|
||||
use core::io::WriterUtil;
|
||||
use core::io;
|
||||
use core::option;
|
||||
use core::str;
|
||||
use core::vec;
|
||||
use std::hash::HashUtil;
|
||||
use std::int;
|
||||
use std::io::WriterUtil;
|
||||
use std::io;
|
||||
use std::option;
|
||||
use std::str;
|
||||
use std::vec;
|
||||
use extra::ebml::reader;
|
||||
use extra::ebml;
|
||||
use extra::serialize::Decodable;
|
||||
use syntax::ast_map;
|
||||
use syntax::attr;
|
||||
use syntax::diagnostic::span_handler;
|
||||
use syntax::parse::token::{ident_interner, special_idents};
|
||||
use syntax::print::pprust;
|
||||
use syntax::{ast, ast_util};
|
||||
|
|
@ -61,7 +59,7 @@ fn lookup_hash(d: ebml::Doc, eq_fn: &fn(x:&[u8]) -> bool, hash: uint) ->
|
|||
let belt = tag_index_buckets_bucket_elt;
|
||||
for reader::tagged_docs(tagged_doc.doc, belt) |elt| {
|
||||
let pos = io::u64_from_be_bytes(*elt.data, elt.start, 4u) as uint;
|
||||
if eq_fn(vec::slice(*elt.data, elt.start + 4u, elt.end)) {
|
||||
if eq_fn(elt.data.slice(elt.start + 4u, elt.end)) {
|
||||
return Some(reader::doc_at(d.data, pos).doc);
|
||||
}
|
||||
};
|
||||
|
|
@ -73,7 +71,7 @@ pub type GetCrateDataCb<'self> = &'self fn(ast::crate_num) -> cmd;
|
|||
pub fn maybe_find_item(item_id: int, items: ebml::Doc) -> Option<ebml::Doc> {
|
||||
fn eq_item(bytes: &[u8], item_id: int) -> bool {
|
||||
return io::u64_from_be_bytes(
|
||||
vec::slice(bytes, 0u, 4u), 0u, 4u) as int
|
||||
bytes.slice(0u, 4u), 0u, 4u) as int
|
||||
== item_id;
|
||||
}
|
||||
lookup_hash(items,
|
||||
|
|
@ -97,13 +95,12 @@ fn lookup_item(item_id: int, data: @~[u8]) -> ebml::Doc {
|
|||
|
||||
#[deriving(Eq)]
|
||||
enum Family {
|
||||
Const, // c
|
||||
ImmStatic, // c
|
||||
MutStatic, // b
|
||||
Fn, // f
|
||||
UnsafeFn, // u
|
||||
PureFn, // p
|
||||
StaticMethod, // F
|
||||
UnsafeStaticMethod, // U
|
||||
PureStaticMethod, // P
|
||||
ForeignFn, // e
|
||||
Type, // y
|
||||
ForeignType, // T
|
||||
|
|
@ -122,13 +119,12 @@ enum Family {
|
|||
fn item_family(item: ebml::Doc) -> Family {
|
||||
let fam = reader::get_doc(item, tag_items_data_item_family);
|
||||
match reader::doc_as_u8(fam) as char {
|
||||
'c' => Const,
|
||||
'c' => ImmStatic,
|
||||
'b' => MutStatic,
|
||||
'f' => Fn,
|
||||
'u' => UnsafeFn,
|
||||
'p' => PureFn,
|
||||
'F' => StaticMethod,
|
||||
'U' => UnsafeStaticMethod,
|
||||
'P' => PureStaticMethod,
|
||||
'e' => ForeignFn,
|
||||
'y' => Type,
|
||||
'T' => ForeignType,
|
||||
|
|
@ -321,11 +317,11 @@ fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::crate_num)
|
|||
-> def_like {
|
||||
let fam = item_family(item);
|
||||
match fam {
|
||||
Const => dl_def(ast::def_const(did)),
|
||||
ImmStatic => dl_def(ast::def_static(did, false)),
|
||||
MutStatic => dl_def(ast::def_static(did, true)),
|
||||
Struct => dl_def(ast::def_struct(did)),
|
||||
UnsafeFn => dl_def(ast::def_fn(did, ast::unsafe_fn)),
|
||||
Fn => dl_def(ast::def_fn(did, ast::impure_fn)),
|
||||
PureFn => dl_def(ast::def_fn(did, ast::pure_fn)),
|
||||
ForeignFn => dl_def(ast::def_fn(did, ast::extern_fn)),
|
||||
UnsafeStaticMethod => {
|
||||
let trait_did_opt = translated_parent_item_opt(cnum, item);
|
||||
|
|
@ -335,10 +331,6 @@ fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::crate_num)
|
|||
let trait_did_opt = translated_parent_item_opt(cnum, item);
|
||||
dl_def(ast::def_static_method(did, trait_did_opt, ast::impure_fn))
|
||||
}
|
||||
PureStaticMethod => {
|
||||
let trait_did_opt = translated_parent_item_opt(cnum, item);
|
||||
dl_def(ast::def_static_method(did, trait_did_opt, ast::pure_fn))
|
||||
}
|
||||
Type | ForeignType => dl_def(ast::def_ty(did)),
|
||||
Mod => dl_def(ast::def_mod(did)),
|
||||
ForeignMod => dl_def(ast::def_foreign_mod(did)),
|
||||
|
|
@ -415,7 +407,7 @@ pub fn get_impl_trait(cdata: cmd,
|
|||
}
|
||||
|
||||
pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
|
||||
name: ast::ident) -> ast::def_id {
|
||||
name: ast::ident) -> Option<ast::def_id> {
|
||||
let items = reader::get_doc(reader::Doc(cdata.data), tag_items);
|
||||
let mut found = None;
|
||||
for reader::tagged_docs(find_item(id, items), tag_item_impl_method)
|
||||
|
|
@ -425,7 +417,7 @@ pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
|
|||
found = Some(translate_def_id(cdata, m_did));
|
||||
}
|
||||
}
|
||||
found.get()
|
||||
found
|
||||
}
|
||||
|
||||
pub fn get_symbol(data: @~[u8], id: ast::node_id) -> ~str {
|
||||
|
|
@ -465,64 +457,192 @@ pub fn each_lang_item(cdata: cmd, f: &fn(ast::node_id, uint) -> bool) -> bool {
|
|||
return true;
|
||||
}
|
||||
|
||||
/// Iterates over all the paths in the given crate.
|
||||
pub fn each_path(intr: @ident_interner,
|
||||
cdata: cmd,
|
||||
get_crate_data: GetCrateDataCb,
|
||||
f: &fn(&str, def_like, ast::visibility) -> bool)
|
||||
-> bool {
|
||||
// FIXME #4572: This function needs to be nuked, as it's impossible to make fast.
|
||||
// It's the source of most of the performance problems when compiling small crates.
|
||||
struct EachItemContext<'self> {
|
||||
intr: @ident_interner,
|
||||
cdata: cmd,
|
||||
get_crate_data: GetCrateDataCb<'self>,
|
||||
path_builder: &'self mut ~str,
|
||||
callback: &'self fn(&str, def_like, ast::visibility) -> bool,
|
||||
}
|
||||
|
||||
let root = reader::Doc(cdata.data);
|
||||
let items = reader::get_doc(root, tag_items);
|
||||
let items_data = reader::get_doc(items, tag_items_data);
|
||||
impl<'self> EachItemContext<'self> {
|
||||
// Pushes the given name and returns the old length.
|
||||
fn push_name(&mut self, string: &str) -> uint {
|
||||
let path_len = self.path_builder.len();
|
||||
if path_len != 0 {
|
||||
self.path_builder.push_str("::")
|
||||
}
|
||||
self.path_builder.push_str(string);
|
||||
path_len
|
||||
}
|
||||
|
||||
// First, go through all the explicit items.
|
||||
for reader::tagged_docs(items_data, tag_items_data_item) |item_doc| {
|
||||
let path = ast_map::path_to_str(item_path(item_doc), intr);
|
||||
let path_is_empty = path.is_empty();
|
||||
if !path_is_empty {
|
||||
// Extract the def ID.
|
||||
let def_id = item_def_id(item_doc, cdata);
|
||||
// Pops the given name.
|
||||
fn pop_name(&mut self, old_len: uint) {
|
||||
// XXX(pcwalton): There's no safe function to do this. :(
|
||||
unsafe {
|
||||
str::raw::set_len(self.path_builder, old_len)
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the def for this item.
|
||||
debug!("(each_path) yielding explicit item: %s", path);
|
||||
let def_like = item_to_def_like(item_doc, def_id, cdata.cnum);
|
||||
|
||||
let vis = item_visibility(item_doc);
|
||||
|
||||
// Hand the information off to the iteratee.
|
||||
if !f(path, def_like, vis) {
|
||||
return false;
|
||||
fn process_item_and_pop_name(&mut self,
|
||||
doc: ebml::Doc,
|
||||
def_id: ast::def_id,
|
||||
old_len: uint)
|
||||
-> bool {
|
||||
let def_like = item_to_def_like(doc, def_id, self.cdata.cnum);
|
||||
match def_like {
|
||||
dl_def(def) => {
|
||||
debug!("(iterating over each item of a module) processing \
|
||||
`%s` (def %?)",
|
||||
*self.path_builder,
|
||||
def);
|
||||
}
|
||||
_ => {
|
||||
debug!("(iterating over each item of a module) processing \
|
||||
`%s` (%d:%d)",
|
||||
*self.path_builder,
|
||||
def_id.crate,
|
||||
def_id.node);
|
||||
}
|
||||
}
|
||||
|
||||
// If this is a module, find the reexports.
|
||||
for each_reexport(item_doc) |reexport_doc| {
|
||||
let def_id_doc =
|
||||
reader::get_doc(reexport_doc,
|
||||
tag_items_data_item_reexport_def_id);
|
||||
let def_id = reader::with_doc_data(def_id_doc, parse_def_id);
|
||||
let def_id = translate_def_id(cdata, def_id);
|
||||
let vis = item_visibility(doc);
|
||||
|
||||
let reexport_name_doc =
|
||||
reader::get_doc(reexport_doc,
|
||||
tag_items_data_item_reexport_name);
|
||||
let reexport_name = reexport_name_doc.as_str_slice();
|
||||
let mut continue = (self.callback)(*self.path_builder, def_like, vis);
|
||||
|
||||
let reexport_path;
|
||||
if path_is_empty {
|
||||
reexport_path = reexport_name.to_owned();
|
||||
} else {
|
||||
reexport_path = path + "::" + reexport_name;
|
||||
let family = item_family(doc);
|
||||
if family == ForeignMod {
|
||||
// These are unnamed; pop the name now.
|
||||
self.pop_name(old_len)
|
||||
}
|
||||
|
||||
if continue {
|
||||
// Recurse if necessary.
|
||||
match family {
|
||||
Mod | ForeignMod | Trait | Impl => {
|
||||
continue = self.each_item_of_module(def_id);
|
||||
}
|
||||
ImmStatic | MutStatic | Struct | UnsafeFn | Fn | ForeignFn |
|
||||
UnsafeStaticMethod | StaticMethod | Type | ForeignType |
|
||||
Variant | Enum | PublicField | PrivateField |
|
||||
InheritedField => {}
|
||||
}
|
||||
}
|
||||
|
||||
// This reexport may be in yet another crate
|
||||
let other_crates_items = if def_id.crate == cdata.cnum {
|
||||
items
|
||||
if family != ForeignMod {
|
||||
self.pop_name(old_len)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
fn each_item_of_module(&mut self, def_id: ast::def_id) -> bool {
|
||||
// This item might not be in this crate. If it's not, look it up.
|
||||
let (_cdata, items) = if def_id.crate == self.cdata.cnum {
|
||||
let items = reader::get_doc(reader::Doc(self.cdata.data),
|
||||
tag_items);
|
||||
(self.cdata, items)
|
||||
} else {
|
||||
let crate_data = (self.get_crate_data)(def_id.crate);
|
||||
let root = reader::Doc(crate_data.data);
|
||||
(crate_data, reader::get_doc(root, tag_items))
|
||||
};
|
||||
|
||||
// Look up the item.
|
||||
let item_doc = match maybe_find_item(def_id.node, items) {
|
||||
None => return false,
|
||||
Some(item_doc) => item_doc,
|
||||
};
|
||||
|
||||
self.each_child_of_module_or_crate(item_doc)
|
||||
}
|
||||
|
||||
fn each_child_of_module_or_crate(&mut self, item_doc: ebml::Doc) -> bool {
|
||||
let mut continue = true;
|
||||
|
||||
// Iterate over all children.
|
||||
for reader::tagged_docs(item_doc, tag_mod_child) |child_info_doc| {
|
||||
let child_def_id = reader::with_doc_data(child_info_doc,
|
||||
parse_def_id);
|
||||
let child_def_id = translate_def_id(self.cdata, child_def_id);
|
||||
|
||||
// This item may be in yet another crate, if it was the child of
|
||||
// a reexport.
|
||||
let other_crates_items = if child_def_id.crate ==
|
||||
self.cdata.cnum {
|
||||
reader::get_doc(reader::Doc(self.cdata.data), tag_items)
|
||||
} else {
|
||||
let crate_data = get_crate_data(def_id.crate);
|
||||
let crate_data = (self.get_crate_data)(child_def_id.crate);
|
||||
let root = reader::Doc(crate_data.data);
|
||||
reader::get_doc(root, tag_items)
|
||||
};
|
||||
|
||||
debug!("(iterating over each item of a module) looking up item \
|
||||
%d:%d in `%s`, crate %d",
|
||||
child_def_id.crate,
|
||||
child_def_id.node,
|
||||
*self.path_builder,
|
||||
self.cdata.cnum);
|
||||
|
||||
// Get the item.
|
||||
match maybe_find_item(child_def_id.node, other_crates_items) {
|
||||
None => {}
|
||||
Some(child_item_doc) => {
|
||||
// Push the name.
|
||||
let child_name = item_name(self.intr, child_item_doc);
|
||||
debug!("(iterating over each item of a module) pushing \
|
||||
name `%s` onto `%s`",
|
||||
token::ident_to_str(&child_name),
|
||||
*self.path_builder);
|
||||
let old_len =
|
||||
self.push_name(token::ident_to_str(&child_name));
|
||||
|
||||
// Process this item.
|
||||
continue = self.process_item_and_pop_name(child_item_doc,
|
||||
child_def_id,
|
||||
old_len);
|
||||
|
||||
if !continue {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !continue {
|
||||
return false
|
||||
}
|
||||
|
||||
// Iterate over reexports.
|
||||
for each_reexport(item_doc) |reexport_doc| {
|
||||
let def_id_doc = reader::get_doc(
|
||||
reexport_doc,
|
||||
tag_items_data_item_reexport_def_id);
|
||||
let orig_def_id = reader::with_doc_data(def_id_doc, parse_def_id);
|
||||
|
||||
// NB: was "cdata"
|
||||
let def_id = translate_def_id(self.cdata, orig_def_id);
|
||||
|
||||
let name_doc = reader::get_doc(reexport_doc,
|
||||
tag_items_data_item_reexport_name);
|
||||
let name = name_doc.as_str_slice();
|
||||
|
||||
// Push the name.
|
||||
debug!("(iterating over each item of a module) pushing \
|
||||
reexported name `%s` onto `%s` (crate %d, orig %d, \
|
||||
in crate %d)",
|
||||
name,
|
||||
*self.path_builder,
|
||||
def_id.crate,
|
||||
orig_def_id.crate,
|
||||
self.cdata.cnum);
|
||||
let old_len = self.push_name(name);
|
||||
|
||||
// This reexport may be in yet another crate.
|
||||
let other_crates_items = if def_id.crate == self.cdata.cnum {
|
||||
reader::get_doc(reader::Doc(self.cdata.data), tag_items)
|
||||
} else {
|
||||
let crate_data = (self.get_crate_data)(def_id.crate);
|
||||
let root = reader::Doc(crate_data.data);
|
||||
reader::get_doc(root, tag_items)
|
||||
};
|
||||
|
|
@ -530,29 +650,53 @@ pub fn each_path(intr: @ident_interner,
|
|||
// Get the item.
|
||||
match maybe_find_item(def_id.node, other_crates_items) {
|
||||
None => {}
|
||||
Some(item_doc) => {
|
||||
// Construct the def for this item.
|
||||
let def_like = item_to_def_like(item_doc,
|
||||
def_id,
|
||||
cdata.cnum);
|
||||
|
||||
// Hand the information off to the iteratee.
|
||||
debug!("(each_path) yielding reexported \
|
||||
item: %s", reexport_path);
|
||||
|
||||
if (!f(reexport_path, def_like, ast::public)) {
|
||||
return false;
|
||||
}
|
||||
Some(reexported_item_doc) => {
|
||||
continue = self.process_item_and_pop_name(
|
||||
reexported_item_doc,
|
||||
def_id,
|
||||
old_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
if !continue {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_item_path(cdata: cmd, id: ast::node_id)
|
||||
-> ast_map::path {
|
||||
/// Iterates over all the paths in the given crate.
|
||||
pub fn each_path(intr: @ident_interner,
|
||||
cdata: cmd,
|
||||
get_crate_data: GetCrateDataCb,
|
||||
f: &fn(&str, def_like, ast::visibility) -> bool)
|
||||
-> bool {
|
||||
// FIXME #4572: This function needs to be nuked, as it's impossible to
|
||||
// make fast. It's the source of most of the performance problems when
|
||||
// compiling small crates.
|
||||
|
||||
let root_doc = reader::Doc(cdata.data);
|
||||
let misc_info_doc = reader::get_doc(root_doc, tag_misc_info);
|
||||
let crate_items_doc = reader::get_doc(misc_info_doc,
|
||||
tag_misc_info_crate_items);
|
||||
|
||||
let mut path_builder = ~"";
|
||||
|
||||
let mut context = EachItemContext {
|
||||
intr: intr,
|
||||
cdata: cdata,
|
||||
get_crate_data: get_crate_data,
|
||||
path_builder: &mut path_builder,
|
||||
callback: f,
|
||||
};
|
||||
|
||||
// Iterate over all top-level crate items.
|
||||
context.each_child_of_module_or_crate(crate_items_doc)
|
||||
}
|
||||
|
||||
pub fn get_item_path(cdata: cmd, id: ast::node_id) -> ast_map::path {
|
||||
item_path(lookup_item(id, cdata.data))
|
||||
}
|
||||
|
||||
|
|
@ -598,7 +742,7 @@ pub fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::node_id,
|
|||
let mut infos: ~[ty::VariantInfo] = ~[];
|
||||
let variant_ids = enum_variant_ids(item, cdata);
|
||||
let mut disr_val = 0;
|
||||
for variant_ids.each |did| {
|
||||
for variant_ids.iter().advance |did| {
|
||||
let item = find_item(did.node, items);
|
||||
let ctor_ty = item_type(ast::def_id { crate: cdata.cnum, node: id},
|
||||
item, tcx, cdata);
|
||||
|
|
@ -641,7 +785,7 @@ fn get_explicit_self(item: ebml::Doc) -> ast::explicit_self_ {
|
|||
's' => { return ast::sty_static; }
|
||||
'v' => { return ast::sty_value; }
|
||||
'@' => { return ast::sty_box(get_mutability(string[1])); }
|
||||
'~' => { return ast::sty_uniq(get_mutability(string[1])); }
|
||||
'~' => { return ast::sty_uniq; }
|
||||
'&' => {
|
||||
// FIXME(#4846) expl. region
|
||||
return ast::sty_region(None, get_mutability(string[1]));
|
||||
|
|
@ -668,35 +812,20 @@ fn item_impl_methods(intr: @ident_interner, cdata: cmd, item: ebml::Doc,
|
|||
rslt
|
||||
}
|
||||
|
||||
pub fn get_impls_for_mod(intr: @ident_interner,
|
||||
cdata: cmd,
|
||||
m_id: ast::node_id,
|
||||
name: Option<ast::ident>,
|
||||
get_cdata: &fn(ast::crate_num) -> cmd)
|
||||
-> @~[@resolve::Impl] {
|
||||
/// Returns information about the given implementation.
|
||||
pub fn get_impl(intr: @ident_interner, cdata: cmd, impl_id: ast::node_id)
|
||||
-> resolve::Impl {
|
||||
let data = cdata.data;
|
||||
let mod_item = lookup_item(m_id, data);
|
||||
let mut result = ~[];
|
||||
for reader::tagged_docs(mod_item, tag_mod_impl) |doc| {
|
||||
let did = reader::with_doc_data(doc, parse_def_id);
|
||||
let local_did = translate_def_id(cdata, did);
|
||||
debug!("(get impls for mod) getting did %? for '%?'",
|
||||
local_did, name);
|
||||
// The impl may be defined in a different crate. Ask the caller
|
||||
// to give us the metadata
|
||||
let impl_cdata = get_cdata(local_did.crate);
|
||||
let impl_data = impl_cdata.data;
|
||||
let item = lookup_item(local_did.node, impl_data);
|
||||
let nm = item_name(intr, item);
|
||||
if match name { Some(n) => { n == nm } None => { true } } {
|
||||
let base_tps = item_ty_param_count(item);
|
||||
result.push(@resolve::Impl {
|
||||
did: local_did, ident: nm,
|
||||
methods: item_impl_methods(intr, impl_cdata, item, base_tps)
|
||||
});
|
||||
};
|
||||
let impl_item = lookup_item(impl_id, data);
|
||||
let base_tps = item_ty_param_count(impl_item);
|
||||
resolve::Impl {
|
||||
did: ast::def_id {
|
||||
crate: cdata.cnum,
|
||||
node: impl_id,
|
||||
},
|
||||
ident: item_name(intr, impl_item),
|
||||
methods: item_impl_methods(intr, cdata, impl_item, base_tps),
|
||||
}
|
||||
@result
|
||||
}
|
||||
|
||||
pub fn get_method_name_and_explicit_self(
|
||||
|
|
@ -750,51 +879,18 @@ pub fn get_trait_method_def_ids(cdata: cmd,
|
|||
|
||||
pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd,
|
||||
id: ast::node_id, tcx: ty::ctxt) ->
|
||||
~[ProvidedTraitMethodInfo] {
|
||||
~[@ty::Method] {
|
||||
let data = cdata.data;
|
||||
let item = lookup_item(id, data);
|
||||
let mut result = ~[];
|
||||
|
||||
for reader::tagged_docs(item, tag_item_trait_method) |mth| {
|
||||
for reader::tagged_docs(item, tag_item_trait_method) |mth_id| {
|
||||
let did = item_def_id(mth_id, cdata);
|
||||
let mth = lookup_item(did.node, data);
|
||||
|
||||
if item_method_sort(mth) != 'p' { loop; }
|
||||
|
||||
let did = item_def_id(mth, cdata);
|
||||
|
||||
let type_param_defs =
|
||||
item_ty_param_defs(mth, tcx, cdata,
|
||||
tag_items_data_item_ty_param_bounds);
|
||||
let name = item_name(intr, mth);
|
||||
let ty = doc_type(mth, tcx, cdata);
|
||||
|
||||
let fty = match ty::get(ty).sty {
|
||||
ty::ty_bare_fn(ref f) => copy *f,
|
||||
_ => {
|
||||
tcx.diag.handler().bug("get_provided_trait_methods(): id \
|
||||
has non-function type");
|
||||
}
|
||||
};
|
||||
|
||||
let transformed_self_ty = doc_transformed_self_ty(mth, tcx, cdata);
|
||||
let explicit_self = get_explicit_self(mth);
|
||||
|
||||
let ty_method = ty::Method::new(
|
||||
name,
|
||||
ty::Generics {
|
||||
type_param_defs: type_param_defs,
|
||||
region_param: None
|
||||
},
|
||||
transformed_self_ty,
|
||||
fty,
|
||||
explicit_self,
|
||||
ast::public,
|
||||
did
|
||||
);
|
||||
let provided_trait_method_info = ProvidedTraitMethodInfo {
|
||||
ty: ty_method,
|
||||
def_id: did
|
||||
};
|
||||
|
||||
vec::push(&mut result, provided_trait_method_info);
|
||||
result.push(@get_method(intr, cdata, did.node, tcx));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -845,16 +941,15 @@ pub fn get_static_methods_if_impl(intr: @ident_interner,
|
|||
}
|
||||
|
||||
let mut static_impl_methods = ~[];
|
||||
for impl_method_ids.each |impl_method_id| {
|
||||
for impl_method_ids.iter().advance |impl_method_id| {
|
||||
let impl_method_doc = lookup_item(impl_method_id.node, cdata.data);
|
||||
let family = item_family(impl_method_doc);
|
||||
match family {
|
||||
StaticMethod | UnsafeStaticMethod | PureStaticMethod => {
|
||||
StaticMethod | UnsafeStaticMethod => {
|
||||
let purity;
|
||||
match item_family(impl_method_doc) {
|
||||
StaticMethod => purity = ast::impure_fn,
|
||||
UnsafeStaticMethod => purity = ast::unsafe_fn,
|
||||
PureStaticMethod => purity = ast::pure_fn,
|
||||
_ => fail!()
|
||||
}
|
||||
|
||||
|
|
@ -927,8 +1022,8 @@ pub fn get_item_visibility(cdata: cmd, id: ast::node_id)
|
|||
|
||||
fn family_has_type_params(fam: Family) -> bool {
|
||||
match fam {
|
||||
Const | ForeignType | Mod | ForeignMod | PublicField | PrivateField
|
||||
| ForeignFn => false,
|
||||
ImmStatic | ForeignType | Mod | ForeignMod | PublicField | PrivateField
|
||||
| ForeignFn | MutStatic => false,
|
||||
_ => true
|
||||
}
|
||||
}
|
||||
|
|
@ -958,13 +1053,12 @@ fn describe_def(items: ebml::Doc, id: ast::def_id) -> ~str {
|
|||
|
||||
fn item_family_to_str(fam: Family) -> ~str {
|
||||
match fam {
|
||||
Const => ~"const",
|
||||
ImmStatic => ~"static",
|
||||
MutStatic => ~"static mut",
|
||||
Fn => ~"fn",
|
||||
UnsafeFn => ~"unsafe fn",
|
||||
PureFn => ~"pure fn",
|
||||
StaticMethod => ~"static method",
|
||||
UnsafeStaticMethod => ~"unsafe static method",
|
||||
PureStaticMethod => ~"pure static method",
|
||||
ForeignFn => ~"foreign fn",
|
||||
Type => ~"type",
|
||||
ForeignType => ~"foreign type",
|
||||
|
|
@ -1035,7 +1129,8 @@ fn get_attributes(md: ebml::Doc) -> ~[ast::attribute] {
|
|||
fn list_meta_items(intr: @ident_interner,
|
||||
meta_items: ebml::Doc,
|
||||
out: @io::Writer) {
|
||||
for get_meta_items(meta_items).each |mi| {
|
||||
let r = get_meta_items(meta_items);
|
||||
for r.iter().advance |mi| {
|
||||
out.write_str(fmt!("%s\n", pprust::meta_item_to_str(*mi, intr)));
|
||||
}
|
||||
}
|
||||
|
|
@ -1044,7 +1139,8 @@ fn list_crate_attributes(intr: @ident_interner, md: ebml::Doc, hash: &str,
|
|||
out: @io::Writer) {
|
||||
out.write_str(fmt!("=Crate Attributes (%s)=\n", hash));
|
||||
|
||||
for get_attributes(md).each |attr| {
|
||||
let r = get_attributes(md);
|
||||
for r.iter().advance |attr| {
|
||||
out.write_str(fmt!("%s\n", pprust::attribute_to_str(*attr, intr)));
|
||||
}
|
||||
|
||||
|
|
@ -1084,7 +1180,8 @@ pub fn get_crate_deps(data: @~[u8]) -> ~[crate_dep] {
|
|||
fn list_crate_deps(data: @~[u8], out: @io::Writer) {
|
||||
out.write_str("=External Dependencies=\n");
|
||||
|
||||
for get_crate_deps(data).each |dep| {
|
||||
let r = get_crate_deps(data);
|
||||
for r.iter().advance |dep| {
|
||||
out.write_str(
|
||||
fmt!("%d %s-%s-%s\n",
|
||||
dep.cnum, token::ident_to_str(&dep.name), dep.hash, dep.vers));
|
||||
|
|
|
|||
|
|
@ -10,25 +10,23 @@
|
|||
|
||||
// Metadata encoding
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use metadata::common::*;
|
||||
use metadata::cstore;
|
||||
use metadata::decoder;
|
||||
use metadata::tyencode;
|
||||
use middle::trans::reachable;
|
||||
use middle::ty::node_id_to_type;
|
||||
use middle::ty;
|
||||
use middle;
|
||||
use util::ppaux::ty_to_str;
|
||||
|
||||
use core::hash::HashUtil;
|
||||
use core::hashmap::HashMap;
|
||||
use core::int;
|
||||
use core::io;
|
||||
use core::str;
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use std::hash::HashUtil;
|
||||
use std::hashmap::{HashMap, HashSet};
|
||||
use std::int;
|
||||
use std::io;
|
||||
use std::str;
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
use extra::flate;
|
||||
use extra::serialize::Encodable;
|
||||
use extra;
|
||||
|
|
@ -47,7 +45,7 @@ use syntax::parse::token;
|
|||
use syntax;
|
||||
use writer = extra::ebml::writer;
|
||||
|
||||
use core::cast;
|
||||
use std::cast;
|
||||
|
||||
// used by astencode:
|
||||
type abbrev_map = @mut HashMap<ty::t, tyencode::ty_abbrev>;
|
||||
|
|
@ -60,13 +58,13 @@ pub type encode_inlined_item<'self> = &'self fn(ecx: &EncodeContext,
|
|||
pub struct EncodeParams<'self> {
|
||||
diag: @span_handler,
|
||||
tcx: ty::ctxt,
|
||||
reachable: reachable::map,
|
||||
reexports2: middle::resolve::ExportMap2,
|
||||
item_symbols: &'self HashMap<ast::node_id, ~str>,
|
||||
discrim_symbols: &'self HashMap<ast::node_id, @str>,
|
||||
link_meta: &'self LinkMeta,
|
||||
cstore: @mut cstore::CStore,
|
||||
encode_inlined_item: encode_inlined_item<'self>
|
||||
encode_inlined_item: encode_inlined_item<'self>,
|
||||
reachable: @mut HashSet<ast::node_id>,
|
||||
}
|
||||
|
||||
struct Stats {
|
||||
|
|
@ -75,6 +73,7 @@ struct Stats {
|
|||
dep_bytes: uint,
|
||||
lang_item_bytes: uint,
|
||||
link_args_bytes: uint,
|
||||
misc_bytes: uint,
|
||||
item_bytes: uint,
|
||||
index_bytes: uint,
|
||||
zero_bytes: uint,
|
||||
|
|
@ -87,14 +86,14 @@ pub struct EncodeContext<'self> {
|
|||
diag: @span_handler,
|
||||
tcx: ty::ctxt,
|
||||
stats: @mut Stats,
|
||||
reachable: reachable::map,
|
||||
reexports2: middle::resolve::ExportMap2,
|
||||
item_symbols: &'self HashMap<ast::node_id, ~str>,
|
||||
discrim_symbols: &'self HashMap<ast::node_id, @str>,
|
||||
link_meta: &'self LinkMeta,
|
||||
cstore: &'self cstore::CStore,
|
||||
encode_inlined_item: encode_inlined_item<'self>,
|
||||
type_abbrevs: abbrev_map
|
||||
type_abbrevs: abbrev_map,
|
||||
reachable: @mut HashSet<ast::node_id>,
|
||||
}
|
||||
|
||||
pub fn reachable(ecx: &EncodeContext, id: node_id) -> bool {
|
||||
|
|
@ -152,13 +151,12 @@ fn encode_trait_ref(ebml_w: &mut writer::Encoder,
|
|||
ecx: &EncodeContext,
|
||||
trait_ref: &ty::TraitRef,
|
||||
tag: uint) {
|
||||
let r = ecx.reachable;
|
||||
let ty_str_ctxt = @tyencode::ctxt {
|
||||
diag: ecx.diag,
|
||||
ds: def_to_str,
|
||||
tcx: ecx.tcx,
|
||||
reachable: |a| r.contains(&a),
|
||||
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
|
||||
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)
|
||||
};
|
||||
|
||||
ebml_w.start_tag(tag);
|
||||
tyencode::enc_trait_ref(ebml_w.writer, ty_str_ctxt, trait_ref);
|
||||
|
|
@ -180,14 +178,13 @@ fn encode_ty_type_param_defs(ebml_w: &mut writer::Encoder,
|
|||
ecx: &EncodeContext,
|
||||
params: @~[ty::TypeParameterDef],
|
||||
tag: uint) {
|
||||
let r = ecx.reachable;
|
||||
let ty_str_ctxt = @tyencode::ctxt {
|
||||
diag: ecx.diag,
|
||||
ds: def_to_str,
|
||||
tcx: ecx.tcx,
|
||||
reachable: |a| r.contains(&a),
|
||||
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
|
||||
for params.each |param| {
|
||||
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)
|
||||
};
|
||||
for params.iter().advance |param| {
|
||||
ebml_w.start_tag(tag);
|
||||
tyencode::enc_type_param_def(ebml_w.writer, ty_str_ctxt, param);
|
||||
ebml_w.end_tag();
|
||||
|
|
@ -213,26 +210,24 @@ fn encode_variant_id(ebml_w: &mut writer::Encoder, vid: def_id) {
|
|||
pub fn write_type(ecx: &EncodeContext,
|
||||
ebml_w: &mut writer::Encoder,
|
||||
typ: ty::t) {
|
||||
let r = ecx.reachable;
|
||||
let ty_str_ctxt = @tyencode::ctxt {
|
||||
diag: ecx.diag,
|
||||
ds: def_to_str,
|
||||
tcx: ecx.tcx,
|
||||
reachable: |a| r.contains(&a),
|
||||
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
|
||||
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)
|
||||
};
|
||||
tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
|
||||
}
|
||||
|
||||
pub fn write_vstore(ecx: &EncodeContext,
|
||||
ebml_w: &mut writer::Encoder,
|
||||
vstore: ty::vstore) {
|
||||
let r = ecx.reachable;
|
||||
let ty_str_ctxt = @tyencode::ctxt {
|
||||
diag: ecx.diag,
|
||||
ds: def_to_str,
|
||||
tcx: ecx.tcx,
|
||||
reachable: |a| r.contains(&a),
|
||||
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
|
||||
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)
|
||||
};
|
||||
tyencode::enc_vstore(ebml_w.writer, ty_str_ctxt, vstore);
|
||||
}
|
||||
|
||||
|
|
@ -259,13 +254,12 @@ fn encode_method_fty(ecx: &EncodeContext,
|
|||
typ: &ty::BareFnTy) {
|
||||
ebml_w.start_tag(tag_item_method_fty);
|
||||
|
||||
let r = ecx.reachable;
|
||||
let ty_str_ctxt = @tyencode::ctxt {
|
||||
diag: ecx.diag,
|
||||
ds: def_to_str,
|
||||
tcx: ecx.tcx,
|
||||
reachable: |a| r.contains(&a),
|
||||
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
|
||||
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)
|
||||
};
|
||||
tyencode::enc_bare_fn_ty(ebml_w.writer, ty_str_ctxt, typ);
|
||||
|
||||
ebml_w.end_tag();
|
||||
|
|
@ -325,7 +319,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
|
|||
let mut i = 0;
|
||||
let vi = ty::enum_variants(ecx.tcx,
|
||||
ast::def_id { crate: local_crate, node: id });
|
||||
for variants.each |variant| {
|
||||
for variants.iter().advance |variant| {
|
||||
index.push(entry {val: variant.node.id, pos: ebml_w.writer.tell()});
|
||||
ebml_w.start_tag(tag_items_data_item);
|
||||
encode_def_id(ebml_w, local_def(variant.node.id));
|
||||
|
|
@ -373,7 +367,7 @@ fn encode_path(ecx: &EncodeContext,
|
|||
|
||||
ebml_w.start_tag(tag_path);
|
||||
ebml_w.wr_tagged_u32(tag_path_len, (path.len() + 1) as u32);
|
||||
for path.each |pe| {
|
||||
for path.iter().advance |pe| {
|
||||
encode_path_elt(ecx, ebml_w, *pe);
|
||||
}
|
||||
encode_path_elt(ecx, ebml_w, name);
|
||||
|
|
@ -403,8 +397,8 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext,
|
|||
-> bool {
|
||||
match ecx.tcx.base_impls.find(&exp.def_id) {
|
||||
Some(implementations) => {
|
||||
for implementations.each |&base_impl| {
|
||||
for base_impl.methods.each |&m| {
|
||||
for implementations.iter().advance |&base_impl| {
|
||||
for base_impl.methods.iter().advance |&m| {
|
||||
if m.explicit_self == ast::sty_static {
|
||||
encode_reexported_static_method(ecx, ebml_w, exp,
|
||||
m.did, m.ident);
|
||||
|
|
@ -424,7 +418,7 @@ fn encode_reexported_static_trait_methods(ecx: &EncodeContext,
|
|||
-> bool {
|
||||
match ecx.tcx.trait_methods_cache.find(&exp.def_id) {
|
||||
Some(methods) => {
|
||||
for methods.each |&m| {
|
||||
for methods.iter().advance |&m| {
|
||||
if m.explicit_self == ast::sty_static {
|
||||
encode_reexported_static_method(ecx, ebml_w, exp,
|
||||
m.def_id, m.ident);
|
||||
|
|
@ -473,45 +467,50 @@ fn encode_reexported_static_methods(ecx: &EncodeContext,
|
|||
}
|
||||
}
|
||||
|
||||
fn encode_info_for_mod(ecx: &EncodeContext,
|
||||
ebml_w: &mut writer::Encoder,
|
||||
md: &_mod,
|
||||
id: node_id,
|
||||
path: &[ast_map::path_elt],
|
||||
name: ident) {
|
||||
ebml_w.start_tag(tag_items_data_item);
|
||||
encode_def_id(ebml_w, local_def(id));
|
||||
encode_family(ebml_w, 'm');
|
||||
encode_name(ecx, ebml_w, name);
|
||||
debug!("(encoding info for module) encoding info for module ID %d", id);
|
||||
|
||||
// Encode info about all the module children.
|
||||
for md.items.each |item| {
|
||||
match item.node {
|
||||
item_impl(*) => {
|
||||
let (ident, did) = (item.ident, item.id);
|
||||
debug!("(encoding info for module) ... encoding impl %s \
|
||||
(%?/%?)",
|
||||
ecx.tcx.sess.str_of(ident),
|
||||
did,
|
||||
ast_map::node_id_to_str(ecx.tcx.items, did, token::get_ident_interner()));
|
||||
|
||||
ebml_w.start_tag(tag_mod_impl);
|
||||
ebml_w.wr_str(def_to_str(local_def(did)));
|
||||
ebml_w.end_tag();
|
||||
/// Iterates through "auxiliary node IDs", which are node IDs that describe
|
||||
/// top-level items that are sub-items of the given item. Specifically:
|
||||
///
|
||||
/// * For enums, iterates through the node IDs of the variants.
|
||||
///
|
||||
/// * For newtype structs, iterates through the node ID of the constructor.
|
||||
fn each_auxiliary_node_id(item: @item, callback: &fn(node_id) -> bool)
|
||||
-> bool {
|
||||
let mut continue = true;
|
||||
match item.node {
|
||||
item_enum(ref enum_def, _) => {
|
||||
for enum_def.variants.iter().advance |variant| {
|
||||
continue = callback(variant.node.id);
|
||||
if !continue {
|
||||
break
|
||||
}
|
||||
}
|
||||
_ => {} // FIXME #4573: Encode these too.
|
||||
}
|
||||
item_struct(struct_def, _) => {
|
||||
// If this is a newtype struct, return the constructor.
|
||||
match struct_def.ctor_id {
|
||||
Some(ctor_id) if struct_def.fields.len() > 0 &&
|
||||
struct_def.fields[0].node.kind ==
|
||||
ast::unnamed_field => {
|
||||
continue = callback(ctor_id);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
encode_path(ecx, ebml_w, path, ast_map::path_mod(name));
|
||||
continue
|
||||
}
|
||||
|
||||
// Encode the reexports of this module.
|
||||
fn encode_reexports(ecx: &EncodeContext,
|
||||
ebml_w: &mut writer::Encoder,
|
||||
id: node_id,
|
||||
path: &[ast_map::path_elt]) {
|
||||
debug!("(encoding info for module) encoding reexports for %d", id);
|
||||
match ecx.reexports2.find(&id) {
|
||||
Some(ref exports) => {
|
||||
debug!("(encoding info for module) found reexports for %d", id);
|
||||
for exports.each |exp| {
|
||||
for exports.iter().advance |exp| {
|
||||
debug!("(encoding info for module) reexport '%s' for %d",
|
||||
exp.name, id);
|
||||
ebml_w.start_tag(tag_items_data_item_reexport);
|
||||
|
|
@ -530,6 +529,57 @@ fn encode_info_for_mod(ecx: &EncodeContext,
|
|||
id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_info_for_mod(ecx: &EncodeContext,
|
||||
ebml_w: &mut writer::Encoder,
|
||||
md: &_mod,
|
||||
id: node_id,
|
||||
path: &[ast_map::path_elt],
|
||||
name: ident,
|
||||
vis: visibility) {
|
||||
ebml_w.start_tag(tag_items_data_item);
|
||||
encode_def_id(ebml_w, local_def(id));
|
||||
encode_family(ebml_w, 'm');
|
||||
encode_name(ecx, ebml_w, name);
|
||||
debug!("(encoding info for module) encoding info for module ID %d", id);
|
||||
|
||||
// Encode info about all the module children.
|
||||
for md.items.iter().advance |item| {
|
||||
ebml_w.start_tag(tag_mod_child);
|
||||
ebml_w.wr_str(def_to_str(local_def(item.id)));
|
||||
ebml_w.end_tag();
|
||||
|
||||
for each_auxiliary_node_id(*item) |auxiliary_node_id| {
|
||||
ebml_w.start_tag(tag_mod_child);
|
||||
ebml_w.wr_str(def_to_str(local_def(auxiliary_node_id)));
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
match item.node {
|
||||
item_impl(*) => {
|
||||
let (ident, did) = (item.ident, item.id);
|
||||
debug!("(encoding info for module) ... encoding impl %s \
|
||||
(%?/%?)",
|
||||
ecx.tcx.sess.str_of(ident),
|
||||
did,
|
||||
ast_map::node_id_to_str(ecx.tcx.items, did, token::get_ident_interner()));
|
||||
|
||||
ebml_w.start_tag(tag_mod_impl);
|
||||
ebml_w.wr_str(def_to_str(local_def(did)));
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
encode_path(ecx, ebml_w, path, ast_map::path_mod(name));
|
||||
|
||||
// Encode the reexports of this module, if this module is public.
|
||||
if vis == public {
|
||||
debug!("(encoding info for module) encoding reexports for %d", id);
|
||||
encode_reexports(ecx, ebml_w, id, path);
|
||||
}
|
||||
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
|
@ -574,9 +624,8 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::explic
|
|||
ebml_w.writer.write(&[ '@' as u8 ]);
|
||||
encode_mutability(ebml_w, m);
|
||||
}
|
||||
sty_uniq(m) => {
|
||||
sty_uniq => {
|
||||
ebml_w.writer.write(&[ '~' as u8 ]);
|
||||
encode_mutability(ebml_w, m);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -617,7 +666,7 @@ fn encode_info_for_struct(ecx: &EncodeContext,
|
|||
let tcx = ecx.tcx;
|
||||
/* We encode both private and public fields -- need to include
|
||||
private fields to get the offsets right */
|
||||
for fields.each |field| {
|
||||
for fields.iter().advance |field| {
|
||||
let (nm, vis) = match field.node.kind {
|
||||
named_field(nm, vis) => (nm, vis),
|
||||
unnamed_field => (special_idents::unnamed_field, inherited)
|
||||
|
|
@ -731,8 +780,8 @@ fn encode_info_for_method(ecx: &EncodeContext,
|
|||
}
|
||||
|
||||
let mut combined_ty_params = opt_vec::Empty;
|
||||
combined_ty_params.push_all(&owner_generics.ty_params);
|
||||
combined_ty_params.push_all(&method_generics.ty_params);
|
||||
for owner_generics.ty_params.iter().advance |x| { combined_ty_params.push(copy *x) }
|
||||
for method_generics.ty_params.iter().advance |x| { combined_ty_params.push(copy *x) }
|
||||
let len = combined_ty_params.len();
|
||||
encode_type_param_bounds(ebml_w, ecx, &combined_ty_params);
|
||||
|
||||
|
|
@ -753,7 +802,6 @@ fn encode_info_for_method(ecx: &EncodeContext,
|
|||
fn purity_fn_family(p: purity) -> char {
|
||||
match p {
|
||||
unsafe_fn => 'u',
|
||||
pure_fn => 'p',
|
||||
impure_fn => 'f',
|
||||
extern_fn => 'e'
|
||||
}
|
||||
|
|
@ -762,7 +810,6 @@ fn purity_fn_family(p: purity) -> char {
|
|||
fn purity_static_method_family(p: purity) -> char {
|
||||
match p {
|
||||
unsafe_fn => 'U',
|
||||
pure_fn => 'P',
|
||||
impure_fn => 'F',
|
||||
_ => fail!("extern fn can't be static")
|
||||
}
|
||||
|
|
@ -782,13 +829,6 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
index: @mut ~[entry<int>],
|
||||
path: &[ast_map::path_elt]) {
|
||||
let tcx = ecx.tcx;
|
||||
let must_write =
|
||||
match item.node {
|
||||
item_enum(_, _) | item_impl(*) | item_trait(*) | item_struct(*) |
|
||||
item_mod(*) | item_foreign_mod(*) | item_const(*) => true,
|
||||
_ => false
|
||||
};
|
||||
if !must_write && !reachable(ecx, item.id) { return; }
|
||||
|
||||
fn add_to_index_(item: @item, ebml_w: &writer::Encoder,
|
||||
index: @mut ~[entry<int>]) {
|
||||
|
|
@ -800,13 +840,18 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
ecx.tcx.sess.codemap.span_to_str(item.span));
|
||||
|
||||
match item.node {
|
||||
item_const(_, _) => {
|
||||
item_static(_, m, _) => {
|
||||
add_to_index();
|
||||
ebml_w.start_tag(tag_items_data_item);
|
||||
encode_def_id(ebml_w, local_def(item.id));
|
||||
encode_family(ebml_w, 'c');
|
||||
if m == ast::m_mutbl {
|
||||
encode_family(ebml_w, 'b');
|
||||
} else {
|
||||
encode_family(ebml_w, 'c');
|
||||
}
|
||||
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
||||
encode_symbol(ecx, ebml_w, item.id);
|
||||
encode_name(ecx, ebml_w, item.ident);
|
||||
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
||||
(ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
|
||||
ebml_w.end_tag();
|
||||
|
|
@ -819,6 +864,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
let tps_len = generics.ty_params.len();
|
||||
encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
|
||||
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
||||
encode_name(ecx, ebml_w, item.ident);
|
||||
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
||||
encode_attributes(ebml_w, item.attrs);
|
||||
if tps_len > 0u || should_inline(item.attrs) {
|
||||
|
|
@ -830,15 +876,29 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
}
|
||||
item_mod(ref m) => {
|
||||
add_to_index();
|
||||
encode_info_for_mod(ecx, ebml_w, m, item.id, path, item.ident);
|
||||
encode_info_for_mod(ecx,
|
||||
ebml_w,
|
||||
m,
|
||||
item.id,
|
||||
path,
|
||||
item.ident,
|
||||
item.vis);
|
||||
}
|
||||
item_foreign_mod(_) => {
|
||||
item_foreign_mod(ref fm) => {
|
||||
add_to_index();
|
||||
ebml_w.start_tag(tag_items_data_item);
|
||||
encode_def_id(ebml_w, local_def(item.id));
|
||||
encode_family(ebml_w, 'n');
|
||||
encode_name(ecx, ebml_w, item.ident);
|
||||
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
||||
|
||||
// Encode all the items in this module.
|
||||
for fm.items.iter().advance |foreign_item| {
|
||||
ebml_w.start_tag(tag_mod_child);
|
||||
ebml_w.wr_str(def_to_str(local_def(foreign_item.id)));
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
item_ty(_, ref generics) => {
|
||||
|
|
@ -862,7 +922,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
|
||||
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
||||
encode_name(ecx, ebml_w, item.ident);
|
||||
for (*enum_definition).variants.each |v| {
|
||||
for (*enum_definition).variants.iter().advance |v| {
|
||||
encode_variant_id(ebml_w, local_def(v.node.id));
|
||||
}
|
||||
(ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
|
||||
|
|
@ -896,23 +956,6 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
|
||||
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
||||
|
||||
// If this is a tuple- or enum-like struct, encode the type of the
|
||||
// constructor.
|
||||
if struct_def.fields.len() > 0 &&
|
||||
struct_def.fields[0].node.kind == ast::unnamed_field {
|
||||
let ctor_id = match struct_def.ctor_id {
|
||||
Some(ctor_id) => ctor_id,
|
||||
None => ecx.tcx.sess.bug("struct def didn't have ctor id"),
|
||||
};
|
||||
|
||||
encode_info_for_struct_ctor(ecx,
|
||||
ebml_w,
|
||||
path,
|
||||
item.ident,
|
||||
ctor_id,
|
||||
index);
|
||||
}
|
||||
|
||||
encode_name(ecx, ebml_w, item.ident);
|
||||
encode_attributes(ebml_w, item.attrs);
|
||||
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
||||
|
|
@ -921,7 +964,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
/* Encode def_ids for each field and method
|
||||
for methods, write all the stuff get_trait_method
|
||||
needs to know*/
|
||||
for struct_def.fields.each |f| {
|
||||
for struct_def.fields.iter().advance |f| {
|
||||
match f.node.kind {
|
||||
named_field(ident, vis) => {
|
||||
ebml_w.start_tag(tag_item_field);
|
||||
|
|
@ -942,6 +985,23 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
let bkts = create_index(idx);
|
||||
encode_index(ebml_w, bkts, write_int);
|
||||
ebml_w.end_tag();
|
||||
|
||||
// If this is a tuple- or enum-like struct, encode the type of the
|
||||
// constructor.
|
||||
if struct_def.fields.len() > 0 &&
|
||||
struct_def.fields[0].node.kind == ast::unnamed_field {
|
||||
let ctor_id = match struct_def.ctor_id {
|
||||
Some(ctor_id) => ctor_id,
|
||||
None => ecx.tcx.sess.bug("struct def didn't have ctor id"),
|
||||
};
|
||||
|
||||
encode_info_for_struct_ctor(ecx,
|
||||
ebml_w,
|
||||
path,
|
||||
item.ident,
|
||||
ctor_id,
|
||||
index);
|
||||
}
|
||||
}
|
||||
item_impl(ref generics, opt_trait, ty, ref methods) => {
|
||||
add_to_index();
|
||||
|
|
@ -954,13 +1014,14 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
encode_name(ecx, ebml_w, item.ident);
|
||||
encode_attributes(ebml_w, item.attrs);
|
||||
match ty.node {
|
||||
ast::ty_path(path, _) if path.idents.len() == 1 => {
|
||||
ast::ty_path(path, bounds, _) if path.idents.len() == 1 => {
|
||||
assert!(bounds.is_none());
|
||||
encode_impl_type_basename(ecx, ebml_w,
|
||||
ast_util::path_to_ident(path));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
for methods.each |m| {
|
||||
for methods.iter().advance |m| {
|
||||
ebml_w.start_tag(tag_item_impl_method);
|
||||
let method_def_id = local_def(m.id);
|
||||
let s = def_to_str(method_def_id);
|
||||
|
|
@ -976,9 +1037,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
|
||||
// >:-<
|
||||
let mut impl_path = vec::append(~[], path);
|
||||
impl_path += [ast_map::path_name(item.ident)];
|
||||
impl_path.push(ast_map::path_name(item.ident));
|
||||
|
||||
for methods.each |m| {
|
||||
for methods.iter().advance |m| {
|
||||
index.push(entry {val: m.id, pos: ebml_w.writer.tell()});
|
||||
encode_info_for_method(ecx,
|
||||
ebml_w,
|
||||
|
|
@ -1001,20 +1062,25 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
encode_trait_ref(ebml_w, ecx, trait_def.trait_ref, tag_item_trait_ref);
|
||||
encode_name(ecx, ebml_w, item.ident);
|
||||
encode_attributes(ebml_w, item.attrs);
|
||||
for ty::trait_method_def_ids(tcx, local_def(item.id)).each |&method_def_id| {
|
||||
for ty::trait_method_def_ids(tcx, local_def(item.id)).iter().advance |&method_def_id| {
|
||||
ebml_w.start_tag(tag_item_trait_method);
|
||||
encode_def_id(ebml_w, method_def_id);
|
||||
ebml_w.end_tag();
|
||||
|
||||
ebml_w.start_tag(tag_mod_child);
|
||||
ebml_w.wr_str(def_to_str(method_def_id));
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
||||
for super_traits.each |ast_trait_ref| {
|
||||
for super_traits.iter().advance |ast_trait_ref| {
|
||||
let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id);
|
||||
encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_super_trait_ref);
|
||||
}
|
||||
ebml_w.end_tag();
|
||||
|
||||
// Now output the method info for each method.
|
||||
for ty::trait_method_def_ids(tcx, local_def(item.id)).eachi |i, &method_def_id| {
|
||||
let r = ty::trait_method_def_ids(tcx, local_def(item.id));
|
||||
for r.iter().enumerate().advance |(i, &method_def_id)| {
|
||||
assert_eq!(method_def_id.crate, ast::local_crate);
|
||||
|
||||
let method_ty = ty::method(tcx, method_def_id);
|
||||
|
|
@ -1088,7 +1154,6 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
|
|||
index: @mut ~[entry<int>],
|
||||
path: ast_map::path,
|
||||
abi: AbiSet) {
|
||||
if !reachable(ecx, nitem.id) { return; }
|
||||
index.push(entry { val: nitem.id, pos: ebml_w.writer.tell() });
|
||||
|
||||
ebml_w.start_tag(tag_items_data_item);
|
||||
|
|
@ -1098,6 +1163,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
|
|||
encode_family(ebml_w, purity_fn_family(purity));
|
||||
encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
|
||||
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
|
||||
encode_name(ecx, ebml_w, nitem.ident);
|
||||
if abi.is_intrinsic() {
|
||||
(ecx.encode_inlined_item)(ecx, ebml_w, path, ii_foreign(nitem));
|
||||
} else {
|
||||
|
|
@ -1105,11 +1171,16 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
|
|||
}
|
||||
encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));
|
||||
}
|
||||
foreign_item_const(*) => {
|
||||
foreign_item_static(_, mutbl) => {
|
||||
encode_def_id(ebml_w, local_def(nitem.id));
|
||||
encode_family(ebml_w, 'c');
|
||||
if mutbl {
|
||||
encode_family(ebml_w, 'b');
|
||||
} else {
|
||||
encode_family(ebml_w, 'c');
|
||||
}
|
||||
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
|
||||
encode_symbol(ecx, ebml_w, nitem.id);
|
||||
encode_name(ecx, ebml_w, nitem.ident);
|
||||
encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));
|
||||
}
|
||||
}
|
||||
|
|
@ -1123,9 +1194,13 @@ fn encode_info_for_items(ecx: &EncodeContext,
|
|||
let index = @mut ~[];
|
||||
ebml_w.start_tag(tag_items_data);
|
||||
index.push(entry { val: crate_node_id, pos: ebml_w.writer.tell() });
|
||||
encode_info_for_mod(ecx, ebml_w, &crate.node.module,
|
||||
crate_node_id, [],
|
||||
syntax::parse::token::special_idents::invalid);
|
||||
encode_info_for_mod(ecx,
|
||||
ebml_w,
|
||||
&crate.node.module,
|
||||
crate_node_id,
|
||||
[],
|
||||
syntax::parse::token::special_idents::invalid,
|
||||
public);
|
||||
let items = ecx.tcx.items;
|
||||
|
||||
// See comment in `encode_side_tables_for_ii` in astencode
|
||||
|
|
@ -1154,6 +1229,12 @@ fn encode_info_for_items(ecx: &EncodeContext,
|
|||
visit::visit_foreign_item(ni, (cx, v));
|
||||
match items.get_copy(&ni.id) {
|
||||
ast_map::node_foreign_item(_, abi, _, pt) => {
|
||||
debug!("writing foreign item %s::%s",
|
||||
ast_map::path_to_str(
|
||||
*pt,
|
||||
token::get_ident_interner()),
|
||||
token::ident_to_str(&ni.ident));
|
||||
|
||||
let mut ebml_w = copy ebml_w;
|
||||
// See above
|
||||
let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
|
||||
|
|
@ -1182,13 +1263,13 @@ fn create_index<T:Copy + Hash + IterBytes>(index: ~[entry<T>]) ->
|
|||
~[@~[entry<T>]] {
|
||||
let mut buckets: ~[@mut ~[entry<T>]] = ~[];
|
||||
for uint::range(0u, 256u) |_i| { buckets.push(@mut ~[]); };
|
||||
for index.each |elt| {
|
||||
for index.iter().advance |elt| {
|
||||
let h = elt.val.hash() as uint;
|
||||
buckets[h % 256].push(copy *elt);
|
||||
}
|
||||
|
||||
let mut buckets_frozen = ~[];
|
||||
for buckets.each |bucket| {
|
||||
for buckets.iter().advance |bucket| {
|
||||
buckets_frozen.push(@/*bad*/copy **bucket);
|
||||
}
|
||||
return buckets_frozen;
|
||||
|
|
@ -1201,10 +1282,10 @@ fn encode_index<T>(ebml_w: &mut writer::Encoder,
|
|||
ebml_w.start_tag(tag_index);
|
||||
let mut bucket_locs: ~[uint] = ~[];
|
||||
ebml_w.start_tag(tag_index_buckets);
|
||||
for buckets.each |bucket| {
|
||||
for buckets.iter().advance |bucket| {
|
||||
bucket_locs.push(ebml_w.writer.tell());
|
||||
ebml_w.start_tag(tag_index_buckets_bucket);
|
||||
for (**bucket).each |elt| {
|
||||
for (**bucket).iter().advance |elt| {
|
||||
ebml_w.start_tag(tag_index_buckets_bucket_elt);
|
||||
assert!(elt.pos < 0xffff_ffff);
|
||||
writer.write_be_u32(elt.pos as u32);
|
||||
|
|
@ -1215,7 +1296,7 @@ fn encode_index<T>(ebml_w: &mut writer::Encoder,
|
|||
}
|
||||
ebml_w.end_tag();
|
||||
ebml_w.start_tag(tag_index_table);
|
||||
for bucket_locs.each |pos| {
|
||||
for bucket_locs.iter().advance |pos| {
|
||||
assert!(*pos < 0xffff_ffff);
|
||||
writer.write_be_u32(*pos as u32);
|
||||
}
|
||||
|
|
@ -1261,7 +1342,7 @@ fn encode_meta_item(ebml_w: &mut writer::Encoder, mi: @meta_item) {
|
|||
ebml_w.start_tag(tag_meta_item_name);
|
||||
ebml_w.writer.write(name.as_bytes());
|
||||
ebml_w.end_tag();
|
||||
for items.each |inner_item| {
|
||||
for items.iter().advance |inner_item| {
|
||||
encode_meta_item(ebml_w, *inner_item);
|
||||
}
|
||||
ebml_w.end_tag();
|
||||
|
|
@ -1271,7 +1352,7 @@ fn encode_meta_item(ebml_w: &mut writer::Encoder, mi: @meta_item) {
|
|||
|
||||
fn encode_attributes(ebml_w: &mut writer::Encoder, attrs: &[attribute]) {
|
||||
ebml_w.start_tag(tag_attributes);
|
||||
for attrs.each |attr| {
|
||||
for attrs.iter().advance |attr| {
|
||||
ebml_w.start_tag(tag_attribute);
|
||||
encode_meta_item(ebml_w, attr.node.value);
|
||||
ebml_w.end_tag();
|
||||
|
|
@ -1313,7 +1394,7 @@ fn synthesize_crate_attrs(ecx: &EncodeContext,
|
|||
|
||||
let mut attrs: ~[attribute] = ~[];
|
||||
let mut found_link_attr = false;
|
||||
for crate.node.attrs.each |attr| {
|
||||
for crate.node.attrs.iter().advance |attr| {
|
||||
attrs.push(
|
||||
if "link" != attr::get_attr_name(attr) {
|
||||
copy *attr
|
||||
|
|
@ -1355,13 +1436,12 @@ fn encode_crate_deps(ecx: &EncodeContext,
|
|||
|
||||
// Sanity-check the crate numbers
|
||||
let mut expected_cnum = 1;
|
||||
for deps.each |n| {
|
||||
for deps.iter().advance |n| {
|
||||
assert_eq!(n.cnum, expected_cnum);
|
||||
expected_cnum += 1;
|
||||
}
|
||||
|
||||
// mut -> immutable hack for vec::map
|
||||
deps.slice(0, deps.len()).to_owned()
|
||||
deps
|
||||
}
|
||||
|
||||
// We're just going to write a list of crate 'name-hash-version's, with
|
||||
|
|
@ -1369,7 +1449,8 @@ fn encode_crate_deps(ecx: &EncodeContext,
|
|||
// FIXME (#2166): This is not nearly enough to support correct versioning
|
||||
// but is enough to get transitive crate dependencies working.
|
||||
ebml_w.start_tag(tag_crate_deps);
|
||||
for get_ordered_deps(ecx, cstore).each |dep| {
|
||||
let r = get_ordered_deps(ecx, cstore);
|
||||
for r.iter().advance |dep| {
|
||||
encode_crate_dep(ecx, ebml_w, *dep);
|
||||
}
|
||||
ebml_w.end_tag();
|
||||
|
|
@ -1403,7 +1484,7 @@ fn encode_link_args(ecx: &EncodeContext, ebml_w: &mut writer::Encoder) {
|
|||
ebml_w.start_tag(tag_link_args);
|
||||
|
||||
let link_args = cstore::get_used_link_args(ecx.cstore);
|
||||
for link_args.each |link_arg| {
|
||||
for link_args.iter().advance |link_arg| {
|
||||
ebml_w.start_tag(tag_link_args_arg);
|
||||
ebml_w.writer.write_str(link_arg.to_str());
|
||||
ebml_w.end_tag();
|
||||
|
|
@ -1412,6 +1493,30 @@ fn encode_link_args(ecx: &EncodeContext, ebml_w: &mut writer::Encoder) {
|
|||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
fn encode_misc_info(ecx: &EncodeContext,
|
||||
crate: &crate,
|
||||
ebml_w: &mut writer::Encoder) {
|
||||
ebml_w.start_tag(tag_misc_info);
|
||||
ebml_w.start_tag(tag_misc_info_crate_items);
|
||||
for crate.node.module.items.iter().advance |&item| {
|
||||
ebml_w.start_tag(tag_mod_child);
|
||||
ebml_w.wr_str(def_to_str(local_def(item.id)));
|
||||
ebml_w.end_tag();
|
||||
|
||||
for each_auxiliary_node_id(item) |auxiliary_node_id| {
|
||||
ebml_w.start_tag(tag_mod_child);
|
||||
ebml_w.wr_str(def_to_str(local_def(auxiliary_node_id)));
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
}
|
||||
|
||||
// Encode reexports for the root module.
|
||||
encode_reexports(ecx, ebml_w, 0, []);
|
||||
|
||||
ebml_w.end_tag();
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
fn encode_crate_dep(ecx: &EncodeContext,
|
||||
ebml_w: &mut writer::Encoder,
|
||||
dep: decoder::crate_dep) {
|
||||
|
|
@ -1451,29 +1556,39 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] {
|
|||
dep_bytes: 0,
|
||||
lang_item_bytes: 0,
|
||||
link_args_bytes: 0,
|
||||
misc_bytes: 0,
|
||||
item_bytes: 0,
|
||||
index_bytes: 0,
|
||||
zero_bytes: 0,
|
||||
total_bytes: 0,
|
||||
n_inlines: 0
|
||||
};
|
||||
let EncodeParams{item_symbols, diag, tcx, reachable, reexports2,
|
||||
discrim_symbols, cstore, encode_inlined_item,
|
||||
link_meta, _} = parms;
|
||||
let EncodeParams {
|
||||
item_symbols,
|
||||
diag,
|
||||
tcx,
|
||||
reexports2,
|
||||
discrim_symbols,
|
||||
cstore,
|
||||
encode_inlined_item,
|
||||
link_meta,
|
||||
reachable,
|
||||
_
|
||||
} = parms;
|
||||
let type_abbrevs = @mut HashMap::new();
|
||||
let stats = @mut stats;
|
||||
let ecx = EncodeContext {
|
||||
diag: diag,
|
||||
tcx: tcx,
|
||||
stats: stats,
|
||||
reachable: reachable,
|
||||
reexports2: reexports2,
|
||||
item_symbols: item_symbols,
|
||||
discrim_symbols: discrim_symbols,
|
||||
link_meta: link_meta,
|
||||
cstore: cstore,
|
||||
encode_inlined_item: encode_inlined_item,
|
||||
type_abbrevs: type_abbrevs
|
||||
type_abbrevs: type_abbrevs,
|
||||
reachable: reachable,
|
||||
};
|
||||
|
||||
let mut ebml_w = writer::Encoder(wr as @io::Writer);
|
||||
|
|
@ -1499,6 +1614,11 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] {
|
|||
encode_link_args(&ecx, &mut ebml_w);
|
||||
ecx.stats.link_args_bytes = *wr.pos - i;
|
||||
|
||||
// Encode miscellaneous info.
|
||||
i = *wr.pos;
|
||||
encode_misc_info(&ecx, crate, &mut ebml_w);
|
||||
ecx.stats.misc_bytes = *wr.pos - i;
|
||||
|
||||
// Encode and index the items.
|
||||
ebml_w.start_tag(tag_items);
|
||||
i = *wr.pos;
|
||||
|
|
@ -1514,7 +1634,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] {
|
|||
ecx.stats.total_bytes = *wr.pos;
|
||||
|
||||
if (tcx.sess.meta_stats()) {
|
||||
for wr.bytes.each |e| {
|
||||
for wr.bytes.iter().advance |e| {
|
||||
if *e == 0 {
|
||||
ecx.stats.zero_bytes += 1;
|
||||
}
|
||||
|
|
@ -1526,6 +1646,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] {
|
|||
io::println(fmt!(" dep bytes: %u", ecx.stats.dep_bytes));
|
||||
io::println(fmt!(" lang item bytes: %u", ecx.stats.lang_item_bytes));
|
||||
io::println(fmt!(" link args bytes: %u", ecx.stats.link_args_bytes));
|
||||
io::println(fmt!(" misc bytes: %u", ecx.stats.misc_bytes));
|
||||
io::println(fmt!(" item bytes: %u", ecx.stats.item_bytes));
|
||||
io::println(fmt!(" index bytes: %u", ecx.stats.index_bytes));
|
||||
io::println(fmt!(" zero bytes: %u", ecx.stats.zero_bytes));
|
||||
|
|
@ -1548,7 +1669,6 @@ pub fn encoded_ty(tcx: ty::ctxt, t: ty::t) -> ~str {
|
|||
diag: tcx.diag,
|
||||
ds: def_to_str,
|
||||
tcx: tcx,
|
||||
reachable: |_id| false,
|
||||
abbrevs: tyencode::ac_no_abbrevs};
|
||||
do io::with_str_writer |wr| {
|
||||
tyencode::enc_ty(wr, cx, t);
|
||||
|
|
|
|||
|
|
@ -8,12 +8,11 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::option;
|
||||
use core::os;
|
||||
use core::result;
|
||||
use core::str;
|
||||
use std::option;
|
||||
use std::os;
|
||||
use std::result;
|
||||
use std::str;
|
||||
|
||||
// A module for searching for libraries
|
||||
// FIXME (#2658): I'm not happy how this module turned out. Should
|
||||
|
|
@ -48,7 +47,7 @@ pub fn mk_filesearch(maybe_sysroot: &Option<@Path>,
|
|||
debug!("filesearch: searching additional lib search paths [%?]",
|
||||
self.addl_lib_search_paths.len());
|
||||
// a little weird
|
||||
self.addl_lib_search_paths.each(f);
|
||||
self.addl_lib_search_paths.iter().advance(|path| f(path));
|
||||
|
||||
debug!("filesearch: searching target lib path");
|
||||
if !f(&make_target_lib_path(self.sysroot,
|
||||
|
|
@ -89,7 +88,8 @@ pub fn search<T:Copy>(filesearch: @FileSearch, pick: pick<T>) -> Option<T> {
|
|||
let mut rslt = None;
|
||||
for filesearch.for_each_lib_search_path() |lib_search_path| {
|
||||
debug!("searching %s", lib_search_path.to_str());
|
||||
for os::list_dir_path(lib_search_path).each |path| {
|
||||
let r = os::list_dir_path(lib_search_path);
|
||||
for r.iter().advance |path| {
|
||||
debug!("testing %s", path.to_str());
|
||||
let maybe_picked = pick(*path);
|
||||
if maybe_picked.is_some() {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
//! Finds crate binaries and loads their metadata
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use lib::llvm::{False, llvm, mk_object_file, mk_section_iter};
|
||||
use metadata::decoder;
|
||||
|
|
@ -24,14 +23,14 @@ use syntax::parse::token::ident_interner;
|
|||
use syntax::print::pprust;
|
||||
use syntax::{ast, attr};
|
||||
|
||||
use core::cast;
|
||||
use core::io;
|
||||
use core::option;
|
||||
use core::os::consts::{macos, freebsd, linux, android, win32};
|
||||
use core::ptr;
|
||||
use core::str;
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use std::cast;
|
||||
use std::io;
|
||||
use std::option;
|
||||
use std::os::consts::{macos, freebsd, linux, android, win32};
|
||||
use std::ptr;
|
||||
use std::str;
|
||||
use std::uint;
|
||||
use std::vec;
|
||||
use extra::flate;
|
||||
|
||||
pub enum os {
|
||||
|
|
@ -89,78 +88,76 @@ fn find_library_crate_aux(
|
|||
filesearch: @filesearch::FileSearch
|
||||
) -> Option<(~str, @~[u8])> {
|
||||
let crate_name = crate_name_from_metas(cx.metas);
|
||||
let prefix: ~str = prefix + crate_name + "-";
|
||||
let suffix: ~str = /*bad*/copy suffix;
|
||||
let prefix = prefix + crate_name + "-";
|
||||
|
||||
let mut matches = ~[];
|
||||
filesearch::search(filesearch, |path| {
|
||||
filesearch::search(filesearch, |path| -> Option<()> {
|
||||
debug!("inspecting file %s", path.to_str());
|
||||
let f: ~str = path.filename().get();
|
||||
if !(f.starts_with(prefix) && f.ends_with(suffix)) {
|
||||
debug!("skipping %s, doesn't look like %s*%s", path.to_str(),
|
||||
prefix, suffix);
|
||||
option::None::<()>
|
||||
} else {
|
||||
debug!("%s is a candidate", path.to_str());
|
||||
match get_metadata_section(cx.os, path) {
|
||||
option::Some(cvec) => {
|
||||
if !crate_matches(cvec, cx.metas, cx.hash) {
|
||||
debug!("skipping %s, metadata doesn't match",
|
||||
path.to_str());
|
||||
option::None::<()>
|
||||
} else {
|
||||
debug!("found %s with matching metadata", path.to_str());
|
||||
matches.push((path.to_str(), cvec));
|
||||
option::None::<()>
|
||||
match path.filename() {
|
||||
Some(ref f) if f.starts_with(prefix) && f.ends_with(suffix) => {
|
||||
debug!("%s is a candidate", path.to_str());
|
||||
match get_metadata_section(cx.os, path) {
|
||||
Some(cvec) =>
|
||||
if !crate_matches(cvec, cx.metas, cx.hash) {
|
||||
debug!("skipping %s, metadata doesn't match",
|
||||
path.to_str());
|
||||
None
|
||||
} else {
|
||||
debug!("found %s with matching metadata", path.to_str());
|
||||
matches.push((path.to_str(), cvec));
|
||||
None
|
||||
},
|
||||
_ => {
|
||||
debug!("could not load metadata for %s", path.to_str());
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
debug!("could not load metadata for %s", path.to_str());
|
||||
option::None::<()>
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
debug!("skipping %s, doesn't look like %s*%s", path.to_str(),
|
||||
prefix, suffix);
|
||||
None
|
||||
}
|
||||
}});
|
||||
|
||||
match matches.len() {
|
||||
0 => None,
|
||||
1 => Some(matches[0]),
|
||||
_ => {
|
||||
cx.diag.span_err(
|
||||
cx.span, fmt!("multiple matching crates for `%s`", crate_name));
|
||||
cx.diag.handler().note("candidates:");
|
||||
for matches.iter().advance |&(ident, data)| {
|
||||
cx.diag.handler().note(fmt!("path: %s", ident));
|
||||
let attrs = decoder::get_crate_attributes(data);
|
||||
note_linkage_attrs(cx.intr, cx.diag, attrs);
|
||||
}
|
||||
cx.diag.handler().abort_if_errors();
|
||||
None
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if matches.is_empty() {
|
||||
None
|
||||
} else if matches.len() == 1u {
|
||||
Some(/*bad*/copy matches[0])
|
||||
} else {
|
||||
cx.diag.span_err(
|
||||
cx.span, fmt!("multiple matching crates for `%s`", crate_name));
|
||||
cx.diag.handler().note("candidates:");
|
||||
for matches.each |&(ident, data)| {
|
||||
cx.diag.handler().note(fmt!("path: %s", ident));
|
||||
let attrs = decoder::get_crate_attributes(data);
|
||||
note_linkage_attrs(cx.intr, cx.diag, attrs);
|
||||
}
|
||||
cx.diag.handler().abort_if_errors();
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn crate_name_from_metas(metas: &[@ast::meta_item]) -> @str {
|
||||
let name_items = attr::find_meta_items_by_name(metas, "name");
|
||||
match name_items.last_opt() {
|
||||
Some(i) => {
|
||||
match attr::get_meta_item_value_str(*i) {
|
||||
Some(n) => n,
|
||||
// FIXME (#2406): Probably want a warning here since the user
|
||||
// is using the wrong type of meta item.
|
||||
_ => fail!()
|
||||
}
|
||||
for metas.iter().advance |m| {
|
||||
match m.node {
|
||||
ast::meta_name_value(s, ref l) if s == @"name" =>
|
||||
match l.node {
|
||||
ast::lit_str(s) => return s,
|
||||
_ => ()
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
None => fail!("expected to find the crate name")
|
||||
}
|
||||
fail!("expected to find the crate name")
|
||||
}
|
||||
|
||||
pub fn note_linkage_attrs(intr: @ident_interner,
|
||||
diag: @span_handler,
|
||||
attrs: ~[ast::attribute]) {
|
||||
for attr::find_linkage_metas(attrs).each |mi| {
|
||||
diag.handler().note(fmt!("meta: %s",
|
||||
pprust::meta_item_to_str(*mi,intr)));
|
||||
let r = attr::find_linkage_metas(attrs);
|
||||
for r.iter().advance |mi| {
|
||||
diag.handler().note(fmt!("meta: %s", pprust::meta_item_to_str(*mi,intr)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -182,7 +179,7 @@ pub fn metadata_matches(extern_metas: &[@ast::meta_item],
|
|||
debug!("matching %u metadata requirements against %u items",
|
||||
local_metas.len(), extern_metas.len());
|
||||
|
||||
for local_metas.each |needed| {
|
||||
for local_metas.iter().advance |needed| {
|
||||
if !attr::contains(extern_metas, *needed) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,13 +14,11 @@
|
|||
// tjc note: Would be great to have a `match check` macro equivalent
|
||||
// for some of these
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use middle::ty;
|
||||
|
||||
use core::str;
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
use std::str;
|
||||
use std::uint;
|
||||
use syntax::abi::AbiSet;
|
||||
use syntax::abi;
|
||||
use syntax::ast;
|
||||
|
|
@ -190,11 +188,11 @@ fn parse_trait_store(st: &mut PState) -> ty::TraitStore {
|
|||
fn parse_substs(st: &mut PState, conv: conv_did) -> ty::substs {
|
||||
let self_r = parse_opt(st, |st| parse_region(st) );
|
||||
|
||||
let self_ty = parse_opt(st, |st| parse_ty(st, conv) );
|
||||
let self_ty = parse_opt(st, |st| parse_ty(st, |x,y| conv(x,y)) );
|
||||
|
||||
assert_eq!(next(st), '[');
|
||||
let mut params: ~[ty::t] = ~[];
|
||||
while peek(st) != ']' { params.push(parse_ty(st, conv)); }
|
||||
while peek(st) != ']' { params.push(parse_ty(st, |x,y| conv(x,y))); }
|
||||
st.pos = st.pos + 1u;
|
||||
|
||||
return ty::substs {
|
||||
|
|
@ -262,15 +260,17 @@ fn parse_opt<T>(st: &mut PState, f: &fn(&mut PState) -> T) -> Option<T> {
|
|||
fn parse_str(st: &mut PState, term: char) -> ~str {
|
||||
let mut result = ~"";
|
||||
while peek(st) != term {
|
||||
result += str::from_byte(next_byte(st));
|
||||
unsafe {
|
||||
str::raw::push_byte(&mut result, next_byte(st));
|
||||
}
|
||||
}
|
||||
next(st);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn parse_trait_ref(st: &mut PState, conv: conv_did) -> ty::TraitRef {
|
||||
let def = parse_def(st, NominalType, conv);
|
||||
let substs = parse_substs(st, conv);
|
||||
let def = parse_def(st, NominalType, |x,y| conv(x,y));
|
||||
let substs = parse_substs(st, |x,y| conv(x,y));
|
||||
ty::TraitRef {def_id: def, substs: substs}
|
||||
}
|
||||
|
||||
|
|
@ -300,19 +300,20 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
|
|||
'c' => return ty::mk_char(),
|
||||
't' => {
|
||||
assert_eq!(next(st), '[');
|
||||
let def = parse_def(st, NominalType, conv);
|
||||
let substs = parse_substs(st, conv);
|
||||
let def = parse_def(st, NominalType, |x,y| conv(x,y));
|
||||
let substs = parse_substs(st, |x,y| conv(x,y));
|
||||
assert_eq!(next(st), ']');
|
||||
return ty::mk_enum(st.tcx, def, substs);
|
||||
}
|
||||
'x' => {
|
||||
assert_eq!(next(st), '[');
|
||||
let def = parse_def(st, NominalType, conv);
|
||||
let substs = parse_substs(st, conv);
|
||||
let def = parse_def(st, NominalType, |x,y| conv(x,y));
|
||||
let substs = parse_substs(st, |x,y| conv(x,y));
|
||||
let store = parse_trait_store(st);
|
||||
let mt = parse_mutability(st);
|
||||
let bounds = parse_bounds(st, |x,y| conv(x,y));
|
||||
assert_eq!(next(st), ']');
|
||||
return ty::mk_trait(st.tcx, def, substs, store, mt);
|
||||
return ty::mk_trait(st.tcx, def, substs, store, mt, bounds.builtin_bounds);
|
||||
}
|
||||
'p' => {
|
||||
let did = parse_def(st, TypeParameter, conv);
|
||||
|
|
@ -344,7 +345,7 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
|
|||
'T' => {
|
||||
assert_eq!(next(st), '[');
|
||||
let mut params = ~[];
|
||||
while peek(st) != ']' { params.push(parse_ty(st, conv)); }
|
||||
while peek(st) != ']' { params.push(parse_ty(st, |x,y| conv(x,y))); }
|
||||
st.pos = st.pos + 1u;
|
||||
return ty::mk_tup(st.tcx, params);
|
||||
}
|
||||
|
|
@ -378,15 +379,15 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
|
|||
}
|
||||
}
|
||||
'"' => {
|
||||
let _ = parse_def(st, TypeWithId, conv);
|
||||
let inner = parse_ty(st, conv);
|
||||
let _ = parse_def(st, TypeWithId, |x,y| conv(x,y));
|
||||
let inner = parse_ty(st, |x,y| conv(x,y));
|
||||
inner
|
||||
}
|
||||
'B' => ty::mk_opaque_box(st.tcx),
|
||||
'a' => {
|
||||
assert_eq!(next(st), '[');
|
||||
let did = parse_def(st, NominalType, conv);
|
||||
let substs = parse_substs(st, conv);
|
||||
let did = parse_def(st, NominalType, |x,y| conv(x,y));
|
||||
let substs = parse_substs(st, |x,y| conv(x,y));
|
||||
assert_eq!(next(st), ']');
|
||||
return ty::mk_struct(st.tcx, did, substs);
|
||||
}
|
||||
|
|
@ -439,10 +440,9 @@ fn parse_hex(st: &mut PState) -> uint {
|
|||
fn parse_purity(c: char) -> purity {
|
||||
match c {
|
||||
'u' => unsafe_fn,
|
||||
'p' => pure_fn,
|
||||
'i' => impure_fn,
|
||||
'c' => extern_fn,
|
||||
_ => fail!("parse_purity: bad purity")
|
||||
_ => fail!("parse_purity: bad purity %c", c)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -472,8 +472,8 @@ fn parse_closure_ty(st: &mut PState, conv: conv_did) -> ty::ClosureTy {
|
|||
let purity = parse_purity(next(st));
|
||||
let onceness = parse_onceness(next(st));
|
||||
let region = parse_region(st);
|
||||
let bounds = parse_bounds(st, conv);
|
||||
let sig = parse_sig(st, conv);
|
||||
let bounds = parse_bounds(st, |x,y| conv(x,y));
|
||||
let sig = parse_sig(st, |x,y| conv(x,y));
|
||||
ty::ClosureTy {
|
||||
purity: purity,
|
||||
sigil: sigil,
|
||||
|
|
@ -499,7 +499,7 @@ fn parse_sig(st: &mut PState, conv: conv_did) -> ty::FnSig {
|
|||
assert_eq!(next(st), '[');
|
||||
let mut inputs = ~[];
|
||||
while peek(st) != ']' {
|
||||
inputs.push(parse_ty(st, conv));
|
||||
inputs.push(parse_ty(st, |x,y| conv(x,y)));
|
||||
}
|
||||
st.pos += 1u; // eat the ']'
|
||||
let ret_ty = parse_ty(st, conv);
|
||||
|
|
@ -518,8 +518,8 @@ pub fn parse_def_id(buf: &[u8]) -> ast::def_id {
|
|||
fail!();
|
||||
}
|
||||
|
||||
let crate_part = vec::slice(buf, 0u, colon_idx);
|
||||
let def_part = vec::slice(buf, colon_idx + 1u, len);
|
||||
let crate_part = buf.slice(0u, colon_idx);
|
||||
let def_part = buf.slice(colon_idx + 1u, len);
|
||||
|
||||
let crate_num = match uint::parse_bytes(crate_part, 10u) {
|
||||
Some(cn) => cn as int,
|
||||
|
|
@ -543,8 +543,8 @@ pub fn parse_type_param_def_data(data: &[u8], start: uint,
|
|||
}
|
||||
|
||||
fn parse_type_param_def(st: &mut PState, conv: conv_did) -> ty::TypeParameterDef {
|
||||
ty::TypeParameterDef {def_id: parse_def(st, NominalType, conv),
|
||||
bounds: @parse_bounds(st, conv)}
|
||||
ty::TypeParameterDef {def_id: parse_def(st, NominalType, |x,y| conv(x,y)),
|
||||
bounds: @parse_bounds(st, |x,y| conv(x,y))}
|
||||
}
|
||||
|
||||
fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds {
|
||||
|
|
@ -555,13 +555,13 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds {
|
|||
loop {
|
||||
match next(st) {
|
||||
'S' => {
|
||||
param_bounds.builtin_bounds.add(ty::BoundOwned);
|
||||
param_bounds.builtin_bounds.add(ty::BoundSend);
|
||||
}
|
||||
'C' => {
|
||||
param_bounds.builtin_bounds.add(ty::BoundCopy);
|
||||
}
|
||||
'K' => {
|
||||
param_bounds.builtin_bounds.add(ty::BoundConst);
|
||||
param_bounds.builtin_bounds.add(ty::BoundFreeze);
|
||||
}
|
||||
'O' => {
|
||||
param_bounds.builtin_bounds.add(ty::BoundStatic);
|
||||
|
|
@ -570,7 +570,7 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds {
|
|||
param_bounds.builtin_bounds.add(ty::BoundSized);
|
||||
}
|
||||
'I' => {
|
||||
param_bounds.trait_bounds.push(@parse_trait_ref(st, conv));
|
||||
param_bounds.trait_bounds.push(@parse_trait_ref(st, |x,y| conv(x,y)));
|
||||
}
|
||||
'.' => {
|
||||
return param_bounds;
|
||||
|
|
|
|||
|
|
@ -10,15 +10,14 @@
|
|||
|
||||
// Type encoding
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use middle::ty::param_ty;
|
||||
use middle::ty;
|
||||
|
||||
use core::hashmap::HashMap;
|
||||
use core::io::WriterUtil;
|
||||
use core::io;
|
||||
use core::uint;
|
||||
use std::hashmap::HashMap;
|
||||
use std::io::WriterUtil;
|
||||
use std::io;
|
||||
use std::uint;
|
||||
use syntax::abi::AbiSet;
|
||||
use syntax::ast;
|
||||
use syntax::ast::*;
|
||||
|
|
@ -31,7 +30,6 @@ pub struct ctxt {
|
|||
ds: @fn(def_id) -> ~str,
|
||||
// The type context.
|
||||
tcx: ty::ctxt,
|
||||
reachable: @fn(node_id) -> bool,
|
||||
abbrevs: abbrev_ctxt
|
||||
}
|
||||
|
||||
|
|
@ -125,7 +123,7 @@ fn enc_substs(w: @io::Writer, cx: @ctxt, substs: &ty::substs) {
|
|||
do enc_opt(w, substs.self_r) |r| { enc_region(w, cx, r) }
|
||||
do enc_opt(w, substs.self_ty) |t| { enc_ty(w, cx, t) }
|
||||
w.write_char('[');
|
||||
for substs.tps.each |t| { enc_ty(w, cx, *t); }
|
||||
for substs.tps.iter().advance |t| { enc_ty(w, cx, *t); }
|
||||
w.write_char(']');
|
||||
}
|
||||
|
||||
|
|
@ -261,18 +259,21 @@ fn enc_sty(w: @io::Writer, cx: @ctxt, st: ty::sty) {
|
|||
enc_substs(w, cx, substs);
|
||||
w.write_char(']');
|
||||
}
|
||||
ty::ty_trait(def, ref substs, store, mt) => {
|
||||
ty::ty_trait(def, ref substs, store, mt, bounds) => {
|
||||
w.write_str(&"x[");
|
||||
w.write_str((cx.ds)(def));
|
||||
w.write_char('|');
|
||||
enc_substs(w, cx, substs);
|
||||
enc_trait_store(w, cx, store);
|
||||
enc_mutability(w, mt);
|
||||
let bounds = ty::ParamBounds {builtin_bounds: bounds,
|
||||
trait_bounds: ~[]};
|
||||
enc_bounds(w, cx, &bounds);
|
||||
w.write_char(']');
|
||||
}
|
||||
ty::ty_tup(ts) => {
|
||||
w.write_str(&"T[");
|
||||
for ts.each |t| { enc_ty(w, cx, *t); }
|
||||
for ts.iter().advance |t| { enc_ty(w, cx, *t); }
|
||||
w.write_char(']');
|
||||
}
|
||||
ty::ty_box(mt) => { w.write_char('@'); enc_mt(w, cx, mt); }
|
||||
|
|
@ -347,7 +348,6 @@ fn enc_sigil(w: @io::Writer, sigil: Sigil) {
|
|||
|
||||
fn enc_purity(w: @io::Writer, p: purity) {
|
||||
match p {
|
||||
pure_fn => w.write_char('p'),
|
||||
impure_fn => w.write_char('i'),
|
||||
unsafe_fn => w.write_char('u'),
|
||||
extern_fn => w.write_char('c')
|
||||
|
|
@ -389,7 +389,7 @@ fn enc_closure_ty(w: @io::Writer, cx: @ctxt, ft: &ty::ClosureTy) {
|
|||
|
||||
fn enc_fn_sig(w: @io::Writer, cx: @ctxt, fsig: &ty::FnSig) {
|
||||
w.write_char('[');
|
||||
for fsig.inputs.each |ty| {
|
||||
for fsig.inputs.iter().advance |ty| {
|
||||
enc_ty(w, cx, *ty);
|
||||
}
|
||||
w.write_char(']');
|
||||
|
|
@ -399,15 +399,15 @@ fn enc_fn_sig(w: @io::Writer, cx: @ctxt, fsig: &ty::FnSig) {
|
|||
fn enc_bounds(w: @io::Writer, cx: @ctxt, bs: &ty::ParamBounds) {
|
||||
for bs.builtin_bounds.each |bound| {
|
||||
match bound {
|
||||
ty::BoundOwned => w.write_char('S'),
|
||||
ty::BoundSend => w.write_char('S'),
|
||||
ty::BoundCopy => w.write_char('C'),
|
||||
ty::BoundConst => w.write_char('K'),
|
||||
ty::BoundFreeze => w.write_char('K'),
|
||||
ty::BoundStatic => w.write_char('O'),
|
||||
ty::BoundSized => w.write_char('Z'),
|
||||
}
|
||||
}
|
||||
|
||||
for bs.trait_bounds.each |&tp| {
|
||||
for bs.trait_bounds.iter().advance |&tp| {
|
||||
w.write_char('I');
|
||||
enc_trait_ref(w, cx, tp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -8,7 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use c = metadata::common;
|
||||
use cstore = metadata::cstore;
|
||||
|
|
@ -24,8 +23,8 @@ use middle::{ty, typeck, moves};
|
|||
use middle;
|
||||
use util::ppaux::ty_to_str;
|
||||
|
||||
use core::at_vec;
|
||||
use core::uint;
|
||||
use std::at_vec;
|
||||
use std::uint;
|
||||
use extra::ebml::reader;
|
||||
use extra::ebml;
|
||||
use extra::serialize;
|
||||
|
|
@ -43,7 +42,7 @@ use syntax::parse::token;
|
|||
use syntax;
|
||||
use writer = extra::ebml::writer;
|
||||
|
||||
use core::cast;
|
||||
use std::cast;
|
||||
|
||||
#[cfg(test)] use syntax::parse;
|
||||
#[cfg(test)] use syntax::print::pprust;
|
||||
|
|
@ -319,15 +318,10 @@ fn simplify_ast(ii: &ast::inlined_item) -> ast::inlined_item {
|
|||
});
|
||||
|
||||
match *ii {
|
||||
ast::ii_item(i) => {
|
||||
ast::ii_item(fld.fold_item(i).get()) //hack: we're not dropping items
|
||||
}
|
||||
ast::ii_method(d, m) => {
|
||||
ast::ii_method(d, fld.fold_method(m))
|
||||
}
|
||||
ast::ii_foreign(i) => {
|
||||
ast::ii_foreign(fld.fold_foreign_item(i))
|
||||
}
|
||||
//hack: we're not dropping items
|
||||
ast::ii_item(i) => ast::ii_item(fld.fold_item(i).get()),
|
||||
ast::ii_method(d, m) => ast::ii_method(d, fld.fold_method(m)),
|
||||
ast::ii_foreign(i) => ast::ii_foreign(fld.fold_foreign_item(i))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -346,16 +340,10 @@ fn renumber_ast(xcx: @ExtendedDecodeContext, ii: ast::inlined_item)
|
|||
});
|
||||
|
||||
match ii {
|
||||
ast::ii_item(i) => {
|
||||
ast::ii_item(fld.fold_item(i).get())
|
||||
}
|
||||
ast::ii_method(d, m) => {
|
||||
ast::ii_method(xcx.tr_def_id(d), fld.fold_method(m))
|
||||
}
|
||||
ast::ii_foreign(i) => {
|
||||
ast::ii_foreign(fld.fold_foreign_item(i))
|
||||
}
|
||||
}
|
||||
ast::ii_item(i) => ast::ii_item(fld.fold_item(i).get()),
|
||||
ast::ii_method(d, m) => ast::ii_method(xcx.tr_def_id(d), fld.fold_method(m)),
|
||||
ast::ii_foreign(i) => ast::ii_foreign(fld.fold_foreign_item(i)),
|
||||
}
|
||||
}
|
||||
|
||||
// ______________________________________________________________________
|
||||
|
|
@ -374,22 +362,25 @@ fn decode_def(xcx: @ExtendedDecodeContext, doc: ebml::Doc) -> ast::def {
|
|||
impl tr for ast::def {
|
||||
fn tr(&self, xcx: @ExtendedDecodeContext) -> ast::def {
|
||||
match *self {
|
||||
ast::def_fn(did, p) => { ast::def_fn(did.tr(xcx), p) }
|
||||
ast::def_fn(did, p) => ast::def_fn(did.tr(xcx), p),
|
||||
ast::def_static_method(did, did2_opt, p) => {
|
||||
ast::def_static_method(did.tr(xcx),
|
||||
did2_opt.map(|did2| did2.tr(xcx)),
|
||||
p)
|
||||
}
|
||||
ast::def_method(did0, did1) => {
|
||||
ast::def_method(did0.tr(xcx), did1.map(|did1| did1.tr(xcx)))
|
||||
}
|
||||
ast::def_self_ty(nid) => { ast::def_self_ty(xcx.tr_id(nid)) }
|
||||
ast::def_self(nid, i) => { ast::def_self(xcx.tr_id(nid), i) }
|
||||
ast::def_mod(did) => { ast::def_mod(did.tr(xcx)) }
|
||||
ast::def_foreign_mod(did) => { ast::def_foreign_mod(did.tr(xcx)) }
|
||||
ast::def_const(did) => { ast::def_const(did.tr(xcx)) }
|
||||
ast::def_static(did, m) => { ast::def_static(did.tr(xcx), m) }
|
||||
ast::def_arg(nid, b) => { ast::def_arg(xcx.tr_id(nid), b) }
|
||||
ast::def_local(nid, b) => { ast::def_local(xcx.tr_id(nid), b) }
|
||||
ast::def_variant(e_did, v_did) => {
|
||||
ast::def_variant(e_did.tr(xcx), v_did.tr(xcx))
|
||||
}
|
||||
},
|
||||
ast::def_trait(did) => ast::def_trait(did.tr(xcx)),
|
||||
ast::def_ty(did) => ast::def_ty(did.tr(xcx)),
|
||||
ast::def_prim_ty(p) => ast::def_prim_ty(p),
|
||||
|
|
@ -402,9 +393,7 @@ impl tr for ast::def {
|
|||
xcx.tr_id(nid2),
|
||||
xcx.tr_id(nid3))
|
||||
}
|
||||
ast::def_struct(did) => {
|
||||
ast::def_struct(did.tr(xcx))
|
||||
}
|
||||
ast::def_struct(did) => ast::def_struct(did.tr(xcx)),
|
||||
ast::def_region(nid) => ast::def_region(xcx.tr_id(nid)),
|
||||
ast::def_typaram_binder(nid) => {
|
||||
ast::def_typaram_binder(xcx.tr_id(nid))
|
||||
|
|
@ -419,12 +408,9 @@ impl tr for ast::def {
|
|||
|
||||
impl tr for ty::AutoAdjustment {
|
||||
fn tr(&self, xcx: @ExtendedDecodeContext) -> ty::AutoAdjustment {
|
||||
match self {
|
||||
&ty::AutoAddEnv(r, s) => {
|
||||
ty::AutoAddEnv(r.tr(xcx), s)
|
||||
}
|
||||
|
||||
&ty::AutoDerefRef(ref adr) => {
|
||||
match *self {
|
||||
ty::AutoAddEnv(r, s) => ty::AutoAddEnv(r.tr(xcx), s),
|
||||
ty::AutoDerefRef(ref adr) => {
|
||||
ty::AutoDerefRef(ty::AutoDerefRef {
|
||||
autoderefs: adr.autoderefs,
|
||||
autoref: adr.autoref.map(|ar| ar.tr(xcx)),
|
||||
|
|
@ -612,8 +598,10 @@ fn encode_vtable_res(ecx: &e::EncodeContext,
|
|||
// ty::t doesn't work, and there is no way (atm) to have
|
||||
// hand-written encoding routines combine with auto-generated
|
||||
// ones. perhaps we should fix this.
|
||||
do ebml_w.emit_from_vec(*dr) |ebml_w, vtable_origin| {
|
||||
encode_vtable_origin(ecx, ebml_w, vtable_origin)
|
||||
do ebml_w.emit_from_vec(*dr) |ebml_w, param_tables| {
|
||||
do ebml_w.emit_from_vec(**param_tables) |ebml_w, vtable_origin| {
|
||||
encode_vtable_origin(ecx, ebml_w, vtable_origin)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -645,6 +633,13 @@ fn encode_vtable_origin(ecx: &e::EncodeContext,
|
|||
}
|
||||
}
|
||||
}
|
||||
typeck::vtable_self(def_id) => {
|
||||
do ebml_w.emit_enum_variant("vtable_self", 2u, 1u) |ebml_w| {
|
||||
do ebml_w.emit_enum_variant_arg(0u) |ebml_w| {
|
||||
ebml_w.emit_def_id(def_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -659,13 +654,17 @@ trait vtable_decoder_helpers {
|
|||
impl vtable_decoder_helpers for reader::Decoder {
|
||||
fn read_vtable_res(&mut self, xcx: @ExtendedDecodeContext)
|
||||
-> typeck::vtable_res {
|
||||
@self.read_to_vec(|this| this.read_vtable_origin(xcx))
|
||||
@self.read_to_vec(|this|
|
||||
@this.read_to_vec(|this|
|
||||
this.read_vtable_origin(xcx)))
|
||||
}
|
||||
|
||||
fn read_vtable_origin(&mut self, xcx: @ExtendedDecodeContext)
|
||||
-> typeck::vtable_origin {
|
||||
do self.read_enum("vtable_origin") |this| {
|
||||
do this.read_enum_variant(["vtable_static", "vtable_param"])
|
||||
do this.read_enum_variant(["vtable_static",
|
||||
"vtable_param",
|
||||
"vtable_self"])
|
||||
|this, i| {
|
||||
match i {
|
||||
0 => {
|
||||
|
|
@ -691,6 +690,13 @@ impl vtable_decoder_helpers for reader::Decoder {
|
|||
}
|
||||
)
|
||||
}
|
||||
2 => {
|
||||
typeck::vtable_self(
|
||||
do this.read_enum_variant_arg(0u) |this| {
|
||||
this.read_def_id(xcx)
|
||||
}
|
||||
)
|
||||
}
|
||||
// hard to avoid - user input
|
||||
_ => fail!("bad enum variant")
|
||||
}
|
||||
|
|
@ -708,12 +714,12 @@ trait get_ty_str_ctxt {
|
|||
|
||||
impl<'self> get_ty_str_ctxt for e::EncodeContext<'self> {
|
||||
fn ty_str_ctxt(&self) -> @tyencode::ctxt {
|
||||
let r = self.reachable;
|
||||
@tyencode::ctxt {diag: self.tcx.sess.diagnostic(),
|
||||
ds: e::def_to_str,
|
||||
tcx: self.tcx,
|
||||
reachable: |a| r.contains(&a),
|
||||
abbrevs: tyencode::ac_use_abbrevs(self.type_abbrevs)}
|
||||
@tyencode::ctxt {
|
||||
diag: self.tcx.sess.diagnostic(),
|
||||
ds: e::def_to_str,
|
||||
tcx: self.tcx,
|
||||
abbrevs: tyencode::ac_use_abbrevs(self.type_abbrevs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1110,56 +1116,75 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext,
|
|||
found for id %d (orig %d)",
|
||||
tag, id, id0);
|
||||
|
||||
if tag == (c::tag_table_moves_map as uint) {
|
||||
dcx.maps.moves_map.insert(id);
|
||||
} else {
|
||||
let val_doc = entry_doc.get(c::tag_table_val as uint);
|
||||
let mut val_dsr = reader::Decoder(val_doc);
|
||||
let val_dsr = &mut val_dsr;
|
||||
if tag == (c::tag_table_def as uint) {
|
||||
let def = decode_def(xcx, val_doc);
|
||||
dcx.tcx.def_map.insert(id, def);
|
||||
} else if tag == (c::tag_table_node_type as uint) {
|
||||
let ty = val_dsr.read_ty(xcx);
|
||||
debug!("inserting ty for node %?: %s",
|
||||
id, ty_to_str(dcx.tcx, ty));
|
||||
dcx.tcx.node_types.insert(id as uint, ty);
|
||||
} else if tag == (c::tag_table_node_type_subst as uint) {
|
||||
let tys = val_dsr.read_tys(xcx);
|
||||
dcx.tcx.node_type_substs.insert(id, tys);
|
||||
} else if tag == (c::tag_table_freevars as uint) {
|
||||
let fv_info = @val_dsr.read_to_vec(|val_dsr| {
|
||||
@val_dsr.read_freevar_entry(xcx)
|
||||
});
|
||||
dcx.tcx.freevars.insert(id, fv_info);
|
||||
} else if tag == (c::tag_table_tcache as uint) {
|
||||
let tpbt = val_dsr.read_ty_param_bounds_and_ty(xcx);
|
||||
let lid = ast::def_id { crate: ast::local_crate, node: id };
|
||||
dcx.tcx.tcache.insert(lid, tpbt);
|
||||
} else if tag == (c::tag_table_param_defs as uint) {
|
||||
let bounds = val_dsr.read_type_param_def(xcx);
|
||||
dcx.tcx.ty_param_defs.insert(id, bounds);
|
||||
} else if tag == (c::tag_table_method_map as uint) {
|
||||
dcx.maps.method_map.insert(
|
||||
id,
|
||||
val_dsr.read_method_map_entry(xcx));
|
||||
} else if tag == (c::tag_table_vtable_map as uint) {
|
||||
dcx.maps.vtable_map.insert(id,
|
||||
val_dsr.read_vtable_res(xcx));
|
||||
} else if tag == (c::tag_table_adjustments as uint) {
|
||||
let adj: @ty::AutoAdjustment = @Decodable::decode(val_dsr);
|
||||
adj.tr(xcx);
|
||||
dcx.tcx.adjustments.insert(id, adj);
|
||||
} else if tag == (c::tag_table_capture_map as uint) {
|
||||
let cvars =
|
||||
at_vec::to_managed_consume(
|
||||
val_dsr.read_to_vec(
|
||||
|val_dsr| val_dsr.read_capture_var(xcx)));
|
||||
dcx.maps.capture_map.insert(id, cvars);
|
||||
} else {
|
||||
match c::astencode_tag::from_uint(tag) {
|
||||
None => {
|
||||
xcx.dcx.tcx.sess.bug(
|
||||
fmt!("unknown tag found in side tables: %x", tag));
|
||||
}
|
||||
Some(value) => if value == c::tag_table_moves_map {
|
||||
dcx.maps.moves_map.insert(id);
|
||||
} else {
|
||||
let val_doc = entry_doc.get(c::tag_table_val as uint);
|
||||
let mut val_dsr = reader::Decoder(val_doc);
|
||||
let val_dsr = &mut val_dsr;
|
||||
|
||||
match value {
|
||||
c::tag_table_def => {
|
||||
let def = decode_def(xcx, val_doc);
|
||||
dcx.tcx.def_map.insert(id, def);
|
||||
}
|
||||
c::tag_table_node_type => {
|
||||
let ty = val_dsr.read_ty(xcx);
|
||||
debug!("inserting ty for node %?: %s",
|
||||
id, ty_to_str(dcx.tcx, ty));
|
||||
dcx.tcx.node_types.insert(id as uint, ty);
|
||||
}
|
||||
c::tag_table_node_type_subst => {
|
||||
let tys = val_dsr.read_tys(xcx);
|
||||
dcx.tcx.node_type_substs.insert(id, tys);
|
||||
}
|
||||
c::tag_table_freevars => {
|
||||
let fv_info = @val_dsr.read_to_vec(|val_dsr| {
|
||||
@val_dsr.read_freevar_entry(xcx)
|
||||
});
|
||||
dcx.tcx.freevars.insert(id, fv_info);
|
||||
}
|
||||
c::tag_table_tcache => {
|
||||
let tpbt = val_dsr.read_ty_param_bounds_and_ty(xcx);
|
||||
let lid = ast::def_id { crate: ast::local_crate, node: id };
|
||||
dcx.tcx.tcache.insert(lid, tpbt);
|
||||
}
|
||||
c::tag_table_param_defs => {
|
||||
let bounds = val_dsr.read_type_param_def(xcx);
|
||||
dcx.tcx.ty_param_defs.insert(id, bounds);
|
||||
}
|
||||
c::tag_table_method_map => {
|
||||
dcx.maps.method_map.insert(
|
||||
id,
|
||||
val_dsr.read_method_map_entry(xcx));
|
||||
}
|
||||
c::tag_table_vtable_map => {
|
||||
dcx.maps.vtable_map.insert(id,
|
||||
val_dsr.read_vtable_res(xcx));
|
||||
}
|
||||
c::tag_table_adjustments => {
|
||||
let adj: @ty::AutoAdjustment = @Decodable::decode(val_dsr);
|
||||
adj.tr(xcx);
|
||||
dcx.tcx.adjustments.insert(id, adj);
|
||||
}
|
||||
c::tag_table_capture_map => {
|
||||
let cvars =
|
||||
at_vec::to_managed_consume(
|
||||
val_dsr.read_to_vec(
|
||||
|val_dsr| val_dsr.read_capture_var(xcx)));
|
||||
dcx.maps.capture_map.insert(id, cvars);
|
||||
}
|
||||
_ => {
|
||||
xcx.dcx.tcx.sess.bug(
|
||||
fmt!("unknown tag found in side tables: %x", tag));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug!(">< Side table doc loaded");
|
||||
|
|
@ -1217,7 +1242,7 @@ fn mk_ctxt() -> @fake_ext_ctxt {
|
|||
|
||||
#[cfg(test)]
|
||||
fn roundtrip(in_item: Option<@ast::item>) {
|
||||
use core::io;
|
||||
use std::io;
|
||||
|
||||
let in_item = in_item.get();
|
||||
let bytes = do io::with_bytes_writer |wr| {
|
||||
|
|
|
|||
|
|
@ -17,10 +17,9 @@
|
|||
// 3. assignments do not affect things loaned out as immutable
|
||||
// 4. moves do not affect things loaned out in any way
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::hashmap::HashSet;
|
||||
use core::uint;
|
||||
use std::hashmap::HashSet;
|
||||
use std::uint;
|
||||
use mc = middle::mem_categorization;
|
||||
use middle::borrowck::*;
|
||||
use middle::moves;
|
||||
|
|
@ -118,7 +117,7 @@ impl<'self> CheckLoanCtxt<'self> {
|
|||
//! given `loan_path`
|
||||
|
||||
for self.each_in_scope_loan(scope_id) |loan| {
|
||||
for loan.restrictions.each |restr| {
|
||||
for loan.restrictions.iter().advance |restr| {
|
||||
if restr.loan_path == loan_path {
|
||||
if !op(loan, restr) {
|
||||
return false;
|
||||
|
|
@ -152,7 +151,7 @@ impl<'self> CheckLoanCtxt<'self> {
|
|||
debug!("new_loan_indices = %?", new_loan_indices);
|
||||
|
||||
for self.each_issued_loan(scope_id) |issued_loan| {
|
||||
for new_loan_indices.each |&new_loan_index| {
|
||||
for new_loan_indices.iter().advance |&new_loan_index| {
|
||||
let new_loan = &self.all_loans[new_loan_index];
|
||||
self.report_error_if_loans_conflict(issued_loan, new_loan);
|
||||
}
|
||||
|
|
@ -210,7 +209,7 @@ impl<'self> CheckLoanCtxt<'self> {
|
|||
};
|
||||
debug!("illegal_if=%?", illegal_if);
|
||||
|
||||
for loan1.restrictions.each |restr| {
|
||||
for loan1.restrictions.iter().advance |restr| {
|
||||
if !restr.set.intersects(illegal_if) { loop; }
|
||||
if restr.loan_path != loan2.loan_path { loop; }
|
||||
|
||||
|
|
@ -634,7 +633,7 @@ fn check_loans_in_fn<'a>(fk: &visit::fn_kind,
|
|||
closure_id: ast::node_id,
|
||||
span: span) {
|
||||
let cap_vars = this.bccx.capture_map.get(&closure_id);
|
||||
for cap_vars.each |cap_var| {
|
||||
for cap_vars.iter().advance |cap_var| {
|
||||
match cap_var.mode {
|
||||
moves::CapRef | moves::CapCopy => {
|
||||
let var_id = ast_util::def_id_of_def(cap_var.def).node;
|
||||
|
|
|
|||
|
|
@ -359,7 +359,7 @@ of its owner:
|
|||
LIFETIME(LV.f, LT, MQ) // L-Field
|
||||
LIFETIME(LV, LT, MQ)
|
||||
|
||||
LIFETIME(*LV, LT, MQ) // L-Deref-Owned
|
||||
LIFETIME(*LV, LT, MQ) // L-Deref-Send
|
||||
TYPE(LV) = ~Ty
|
||||
LIFETIME(LV, LT, MQ)
|
||||
|
||||
|
|
@ -504,7 +504,7 @@ must prevent the owned pointer `LV` from being mutated, which means
|
|||
that we always add `MUTATE` and `CLAIM` to the restriction set imposed
|
||||
on `LV`:
|
||||
|
||||
RESTRICTIONS(*LV, ACTIONS) = RS, (*LV, ACTIONS) // R-Deref-Owned-Pointer
|
||||
RESTRICTIONS(*LV, ACTIONS) = RS, (*LV, ACTIONS) // R-Deref-Send-Pointer
|
||||
TYPE(LV) = ~Ty
|
||||
RESTRICTIONS(LV, ACTIONS|MUTATE|CLAIM) = RS
|
||||
|
||||
|
|
@ -539,14 +539,14 @@ mutable borrowed pointers.
|
|||
|
||||
### Restrictions for loans of const aliasable pointees
|
||||
|
||||
Const pointers are read-only. There may be `&mut` or `&` aliases, and
|
||||
Freeze pointers are read-only. There may be `&mut` or `&` aliases, and
|
||||
we can not prevent *anything* but moves in that case. So the
|
||||
`RESTRICTIONS` function is only defined if `ACTIONS` is the empty set.
|
||||
Because moves from a `&const` or `@const` lvalue are never legal, it
|
||||
is not necessary to add any restrictions at all to the final
|
||||
result.
|
||||
|
||||
RESTRICTIONS(*LV, []) = [] // R-Deref-Const-Borrowed
|
||||
RESTRICTIONS(*LV, []) = [] // R-Deref-Freeze-Borrowed
|
||||
TYPE(LV) = &const Ty or @const Ty
|
||||
|
||||
### Restrictions for loans of mutable borrowed pointees
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
* Computes moves.
|
||||
*/
|
||||
|
||||
use core::prelude::*;
|
||||
use mc = middle::mem_categorization;
|
||||
use middle::borrowck::*;
|
||||
use middle::borrowck::move_data::*;
|
||||
|
|
@ -71,7 +70,7 @@ pub fn gather_captures(bccx: @BorrowckCtxt,
|
|||
move_data: &mut MoveData,
|
||||
closure_expr: @ast::expr) {
|
||||
let captured_vars = bccx.capture_map.get(&closure_expr.id);
|
||||
for captured_vars.each |captured_var| {
|
||||
for captured_vars.iter().advance |captured_var| {
|
||||
match captured_var.mode {
|
||||
moves::CapMove => {
|
||||
let fvar_id = ast_util::def_id_of_def(captured_var.def).node;
|
||||
|
|
@ -101,9 +100,7 @@ fn check_is_legal_to_move_from(bccx: @BorrowckCtxt,
|
|||
cmt0: mc::cmt,
|
||||
cmt: mc::cmt) -> bool {
|
||||
match cmt.cat {
|
||||
mc::cat_stack_upvar(*) |
|
||||
mc::cat_implicit_self(*) |
|
||||
mc::cat_copied_upvar(*) |
|
||||
mc::cat_deref(_, _, mc::region_ptr(*)) |
|
||||
mc::cat_deref(_, _, mc::gc_ptr(*)) |
|
||||
mc::cat_deref(_, _, mc::unsafe_ptr(*)) => {
|
||||
|
|
@ -114,6 +111,27 @@ fn check_is_legal_to_move_from(bccx: @BorrowckCtxt,
|
|||
false
|
||||
}
|
||||
|
||||
// These are separate from the above cases for a better error message.
|
||||
mc::cat_stack_upvar(*) |
|
||||
mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Many, _ }) => {
|
||||
let once_hint = if bccx.tcx.sess.once_fns() {
|
||||
" (unless the destination closure type is `once fn')"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
bccx.span_err(
|
||||
cmt0.span,
|
||||
fmt!("cannot move out of %s%s", bccx.cmt_to_str(cmt), once_hint));
|
||||
false
|
||||
}
|
||||
|
||||
// Can move out of captured upvars only if the destination closure
|
||||
// type is 'once'. 1-shot stack closures emit the copied_upvar form
|
||||
// (see mem_categorization.rs).
|
||||
mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Once, _ }) => {
|
||||
true
|
||||
}
|
||||
|
||||
// It seems strange to allow a move out of a static item,
|
||||
// but what happens in practice is that you have a
|
||||
// reference to a constant with a type that should be
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
//! This module implements the check that the lifetime of a borrow
|
||||
//! does not exceed the lifetime of the value being borrowed.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use middle::borrowck::*;
|
||||
use mc = middle::mem_categorization;
|
||||
|
|
@ -109,7 +108,7 @@ impl GuaranteeLifetimeContext {
|
|||
}
|
||||
|
||||
mc::cat_downcast(base) |
|
||||
mc::cat_deref(base, _, mc::uniq_ptr(*)) | // L-Deref-Owned
|
||||
mc::cat_deref(base, _, mc::uniq_ptr(*)) | // L-Deref-Send
|
||||
mc::cat_interior(base, _) => { // L-Field
|
||||
self.check(base, discr_scope)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
// their associated scopes. In phase two, checking loans, we will then make
|
||||
// sure that all of these loans are honored.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use middle::borrowck::*;
|
||||
use middle::borrowck::move_data::MoveData;
|
||||
|
|
@ -229,8 +228,8 @@ fn gather_loans_in_expr(ex: @ast::expr,
|
|||
|
||||
ast::expr_match(ex_v, ref arms) => {
|
||||
let cmt = this.bccx.cat_expr(ex_v);
|
||||
for arms.each |arm| {
|
||||
for arm.pats.each |pat| {
|
||||
for arms.iter().advance |arm| {
|
||||
for arm.pats.iter().advance |pat| {
|
||||
this.gather_pat(cmt, *pat, arm.body.node.id, ex.id);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,8 @@
|
|||
|
||||
//! Computes the restrictions that result from a borrow.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::vec;
|
||||
use std::vec;
|
||||
use middle::borrowck::*;
|
||||
use mc = middle::mem_categorization;
|
||||
use middle::ty;
|
||||
|
|
@ -103,7 +102,7 @@ impl RestrictionsContext {
|
|||
}
|
||||
|
||||
mc::cat_deref(cmt_base, _, mc::uniq_ptr(*)) => {
|
||||
// R-Deref-Owned-Pointer
|
||||
// R-Deref-Send-Pointer
|
||||
//
|
||||
// When we borrow the interior of an owned pointer, we
|
||||
// cannot permit the base to be mutated, because that
|
||||
|
|
@ -125,7 +124,7 @@ impl RestrictionsContext {
|
|||
|
||||
mc::cat_deref(_, _, mc::region_ptr(m_const, _)) |
|
||||
mc::cat_deref(_, _, mc::gc_ptr(m_const)) => {
|
||||
// R-Deref-Const-Borrowed
|
||||
// R-Deref-Freeze-Borrowed
|
||||
self.check_no_mutability_control(cmt, restrictions);
|
||||
Safe
|
||||
}
|
||||
|
|
@ -140,7 +139,7 @@ impl RestrictionsContext {
|
|||
// static errors. For example, if there is code like
|
||||
//
|
||||
// let v = @mut ~[1, 2, 3];
|
||||
// for v.each |e| {
|
||||
// for v.iter().advance |e| {
|
||||
// v.push(e + 1);
|
||||
// }
|
||||
//
|
||||
|
|
@ -152,7 +151,7 @@ impl RestrictionsContext {
|
|||
//
|
||||
// let v = @mut ~[1, 2, 3];
|
||||
// let w = v;
|
||||
// for v.each |e| {
|
||||
// for v.iter().advance |e| {
|
||||
// w.push(e + 1);
|
||||
// }
|
||||
//
|
||||
|
|
@ -165,7 +164,7 @@ impl RestrictionsContext {
|
|||
// }
|
||||
// ...
|
||||
// let v: &V = ...;
|
||||
// for v.get_list().each |e| {
|
||||
// for v.get_list().iter().advance |e| {
|
||||
// v.get_list().push(e + 1);
|
||||
// }
|
||||
match opt_loan_path(cmt_base) {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue