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:
Brian Anderson 2013-07-02 17:36:58 -07:00
commit 1098d6980b
765 changed files with 23500 additions and 17316 deletions

View file

@ -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 {

View file

@ -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;

View file

@ -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")) {

View file

@ -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");

View file

@ -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

View file

@ -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")

View file

@ -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/

View file

@ -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>

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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"'

View file

@ -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(),
}
}

View file

@ -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

View file

@ -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();

View file

@ -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;

View file

@ -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))
}
}

View file

@ -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();

View 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
View 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

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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]);
}
}

View file

@ -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;

View file

@ -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() {

View file

@ -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;
}

View file

@ -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);

View file

@ -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)]

View file

@ -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);

View file

@ -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));
}
}
}

View file

@ -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() {

View file

@ -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 {

View file

@ -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
};

View file

@ -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); },
}

View file

@ -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() {

View file

@ -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;
}
}

View file

@ -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"

View file

@ -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";

View file

@ -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() {

View file

@ -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(&divider);
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);

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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, || {

View file

@ -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];

View file

@ -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)
}
}
}
}

View file

@ -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;

View file

@ -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 {

View file

@ -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("."))
}
}
}

View file

@ -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)
}

View file

@ -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();
}
}
}

View file

@ -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());

View file

@ -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) => {

View file

@ -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;
}

View file

@ -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() {

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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) {

View file

@ -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()));
}
}

View file

@ -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");

View file

@ -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);

View file

@ -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 {

View file

@ -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());

View file

@ -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() {

View file

@ -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);

View file

@ -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| {

View file

@ -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!(

View file

@ -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;

View file

@ -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")]

View file

@ -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(),

View file

@ -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() {

View file

@ -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"; }

View file

@ -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);

View file

@ -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!();

View file

@ -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

View file

@ -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())
}
}

View file

@ -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};

View file

@ -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,

View file

@ -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)
}
})

View file

@ -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);
}
}
}

View file

@ -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
}
}

View file

@ -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() }
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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,

View file

@ -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);

View file

@ -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)
}

View file

@ -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);
}

View file

@ -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));

View file

@ -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);

View file

@ -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() {

View file

@ -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;
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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| {

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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)
}

View file

@ -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);
}
}

View file

@ -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