diff --git a/Makefile.in b/Makefile.in index de30113ca4b6..24cd280386af 100644 --- a/Makefile.in +++ b/Makefile.in @@ -139,11 +139,11 @@ endif # version-string calculation CFG_GIT_DIR := $(CFG_SRC_DIR).git -CFG_RELEASE = 0.7 +CFG_RELEASE = 0.8-pre CFG_VERSION = $(CFG_RELEASE) # windows exe's need numeric versions - don't use anything but # numbers and dots here -CFG_VERSION_WIN = 0.7 +CFG_VERSION_WIN = 0.8 ifneq ($(wildcard $(CFG_GIT)),) ifneq ($(wildcard $(CFG_GIT_DIR)),) diff --git a/configure b/configure index d0a98fbfa75c..12782fa9fdb6 100755 --- a/configure +++ b/configure @@ -402,7 +402,7 @@ fi step_msg "looking for build programs" probe_need CFG_PERL perl -probe_need CFG_CURL curl +probe_need CFG_CURLORWGET curl wget probe_need CFG_PYTHON python2.7 python2.6 python2 python python_version=$($CFG_PYTHON -V 2>&1) diff --git a/doc/rust.md b/doc/rust.md index cc53d7d17a25..42a010b114ab 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -207,7 +207,7 @@ The keywords are the following strings: as break copy -do drop +do else enum extern false fn for if impl @@ -1107,11 +1107,11 @@ The derived types are borrowed pointers with the `'static` lifetime, fixed-size arrays, tuples, and structs. ~~~~ -static bit1: uint = 1 << 0; -static bit2: uint = 1 << 1; +static BIT1: uint = 1 << 0; +static BIT2: uint = 1 << 1; -static bits: [uint, ..2] = [bit1, bit2]; -static string: &'static str = "bitstring"; +static BITS: [uint, ..2] = [BIT1, BIT2]; +static STRING: &'static str = "bitstring"; struct BitsNStrings<'self> { mybits: [uint, ..2], @@ -1119,8 +1119,8 @@ struct BitsNStrings<'self> { } static bits_n_strings: BitsNStrings<'static> = BitsNStrings { - mybits: bits, - mystring: string + mybits: BITS, + mystring: STRING }; ~~~~ @@ -2869,9 +2869,6 @@ The kinds are: : Types of this kind can be safely sent between tasks. This kind includes scalars, owning pointers, owned closures, and structural types containing only other owned types. All `Send` types are `Static`. -`Static` - : Types of this kind do not contain any borrowed pointers; - this can be a useful guarantee for code that breaks borrowing assumptions using [`unsafe` operations](#unsafe-functions). `Copy` : This kind includes all types that can be copied. All types with sendable kind are copyable, as are managed boxes, managed closures, @@ -2879,14 +2876,12 @@ The kinds are: Types with destructors (types that implement `Drop`) can not implement `Copy`. `Drop` : This is not strictly a kind, but its presence interacts with kinds: the `Drop` - trait provides a single method `finalize` that takes no parameters, and is run + trait provides a single method `drop` that takes no parameters, and is run when values of the type are dropped. Such a method is called a "destructor", and are always executed in "top-down" order: a value is completely destroyed before any of the values it owns run their destructors. Only `Send` types that do not implement `Copy` can implement `Drop`. -> **Note:** The `finalize` method may be renamed in future versions of Rust. - _Default_ : Types with destructors, closure environments, and various other _non-first-class_ types, diff --git a/doc/tutorial-container.md b/doc/tutorial-container.md index 66bd0b9c1319..5ed61d693014 100644 --- a/doc/tutorial-container.md +++ b/doc/tutorial-container.md @@ -108,7 +108,7 @@ impl Iterator for ZeroStream { ## Container iterators Containers implement iteration over the contained elements by returning an -iterator object. For example, vectors have four iterators available: +iterator object. For example, vector slices have four iterators available: * `vector.iter()`, for immutable references to the elements * `vector.mut_iter()`, for mutable references to the elements diff --git a/doc/tutorial.md b/doc/tutorial.md index d3113703c7cc..c8280a991827 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -237,8 +237,8 @@ can specify a variable's type by following it with a colon, then the type name. Static items, on the other hand, always require a type annotation. ~~~~ -static monster_factor: float = 57.8; -let monster_size = monster_factor * 10.0; +static MONSTER_FACTOR: float = 57.8; +let monster_size = MONSTER_FACTOR * 10.0; let monster_size: int = 50; ~~~~ diff --git a/mk/platform.mk b/mk/platform.mk index 4bb8de28aefa..61a170c21d51 100644 --- a/mk/platform.mk +++ b/mk/platform.mk @@ -323,9 +323,9 @@ AR_i686-pc-mingw32=$(AR) CFG_LIB_NAME_i686-pc-mingw32=$(1).dll CFG_LIB_GLOB_i686-pc-mingw32=$(1)-*.dll CFG_LIB_DSYM_GLOB_i686-pc-mingw32=$(1)-*.dylib.dSYM -CFG_GCCISH_CFLAGS_i686-pc-mingw32 := -Wall -Werror -g -march=i686 +CFG_GCCISH_CFLAGS_i686-pc-mingw32 := -Wall -Werror -g -m32 -march=i686 -D_WIN32_WINNT=0x0600 CFG_GCCISH_CXXFLAGS_i686-pc-mingw32 := -fno-rtti -CFG_GCCISH_LINK_FLAGS_i686-pc-mingw32 := -shared -fPIC -g +CFG_GCCISH_LINK_FLAGS_i686-pc-mingw32 := -shared -fPIC -g -m32 CFG_GCCISH_DEF_FLAG_i686-pc-mingw32 := CFG_GCCISH_PRE_LIB_FLAGS_i686-pc-mingw32 := CFG_GCCISH_POST_LIB_FLAGS_i686-pc-mingw32 := @@ -367,6 +367,31 @@ CFG_LDPATH_i586-mingw32msvc := CFG_RUN_i586-mingw32msvc= CFG_RUN_TARG_i586-mingw32msvc= +# x86_64-w64-mingw32 configuration +CC_x86_64-w64-mingw32=$(CC) +CXX_x86_64-w64-mingw32=$(CXX) +CPP_x86_64-w64-mingw32=$(CPP) +AR_x86_64-w64-mingw32=$(AR) +CFG_LIB_NAME_x86_64-w64-mingw32=$(1).dll +CFG_LIB_GLOB_x86_64-w64-mingw32=$(1)-*.dll +CFG_LIB_DSYM_GLOB_x86_64-w64-mingw32=$(1)-*.dylib.dSYM +CFG_GCCISH_CFLAGS_x86_64-w64-mingw32 := -Wall -Werror -g -m64 -D_WIN32_WINNT=0x0600 +CFG_GCCISH_CXXFLAGS_x86_64-w64-mingw32 := -fno-rtti +CFG_GCCISH_LINK_FLAGS_x86_64-w64-mingw32 := -shared -fPIC -g -m64 +CFG_GCCISH_DEF_FLAG_x86_64-w64-mingw32 := +CFG_GCCISH_PRE_LIB_FLAGS_x86_64-w64-mingw32 := +CFG_GCCISH_POST_LIB_FLAGS_x86_64-w64-mingw32 := +CFG_DEF_SUFFIX_x86_64-w64-mingw32 := .mingw32.def +CFG_INSTALL_NAME_x86_64-w64-mingw32 = +CFG_LIBUV_LINK_FLAGS_x86_64-w64-mingw32 := -lWs2_32 -lpsapi -liphlpapi +CFG_EXE_SUFFIX_x86_64-w64-mingw32 := .exe +CFG_WINDOWSY_x86_64-w64-mingw32 := 1 +CFG_UNIXY_x86_64-w64-mingw32 := +CFG_PATH_MUNGE_x86_64-w64-mingw32 := +CFG_LDPATH_x86_64-w64-mingw32 :=$(CFG_LDPATH_x86_64-w64-mingw32):$(PATH) +CFG_RUN_x86_64-w64-mingw32=PATH="$(CFG_LDPATH_x86_64-w64-mingw32):$(1)" $(2) +CFG_RUN_TARG_x86_64-w64-mingw32=$(call CFG_RUN_x86_64-w64-mingw32,$(HLIB$(1)_H_$(CFG_BUILD_TRIPLE)),$(2)) + # x86_64-unknown-freebsd configuration CC_x86_64-unknown-freebsd=$(CC) CXX_x86_64-unknown-freebsd=$(CXX) diff --git a/mk/tests.mk b/mk/tests.mk index 35d567ef771b..6b6f515ce2b5 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -15,7 +15,7 @@ # The names of crates that must be tested TEST_TARGET_CRATES = std extra -TEST_HOST_CRATES = syntax rustc rustdoc rusti rust rustpkg +TEST_HOST_CRATES = syntax rustc rustdoc rust rustpkg rusti TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES) # Markdown files under doc/ that should have their code extracted and run @@ -157,6 +157,7 @@ check-test: cleantestlibs cleantmptestlogs all check-stage2-rfail check-lite: cleantestlibs cleantmptestlogs \ check-stage2-std check-stage2-extra check-stage2-rpass \ + check-stage2-rustpkg check-stage2-rusti \ check-stage2-rfail check-stage2-cfail $(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log diff --git a/mk/tools.mk b/mk/tools.mk index 0a901358ac1f..0e83147501cb 100644 --- a/mk/tools.mk +++ b/mk/tools.mk @@ -50,7 +50,7 @@ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4)): \ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4)) \ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4)) @$$(call E, compile_and_link: $$@) - $$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@ + $$(STAGE$(1)_T_$(4)_H_$(3)) $$(WFLAGS_ST$(1)) -o $$@ $$< && touch $$@ $$(TBIN$(1)_T_$(4)_H_$(3))/rustpkg$$(X_$(4)): \ $$(DRIVER_CRATE) \ diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs index 869657326b7d..38289f627418 100644 --- a/src/compiletest/common.rs +++ b/src/compiletest/common.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - #[deriving(Eq)] pub enum mode { mode_compile_fail, diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 82206f12fae2..7d9a7c3ea75d 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -11,21 +11,16 @@ #[crate_type = "bin"]; #[allow(non_camel_case_types)]; +#[allow(unrecognized_lint)]; // NOTE: remove after snapshot +#[deny(warnings)]; -#[no_core]; // XXX: Remove after snapshot -#[no_std]; +extern mod extra; -extern mod core(name = "std", vers = "0.7"); -extern mod extra(name = "extra", vers = "0.7"); - -use core::prelude::*; -use core::*; +use std::os; use extra::getopts; use extra::test; -use core::result::{Ok, Err}; - use common::config; use common::mode_run_pass; use common::mode_run_fail; @@ -42,13 +37,6 @@ pub mod runtest; pub mod common; pub mod errors; -mod std { - pub use core::cmp; - pub use core::str; - pub use core::sys; - pub use core::unstable; -} - pub fn main() { let args = os::args(); let config = parse_config(args); @@ -98,8 +86,8 @@ pub fn parse_config(args: ~[~str]) -> config { run_ignored: getopts::opt_present(matches, "ignored"), filter: if !matches.free.is_empty() { - option::Some(copy matches.free[0]) - } else { option::None }, + Some(copy matches.free[0]) + } else { None }, logfile: getopts::opt_maybe_str(matches, "logfile").map(|s| Path(*s)), runtool: getopts::opt_maybe_str(matches, "runtool"), rustcflags: getopts::opt_maybe_str(matches, "rustcflags"), @@ -148,8 +136,8 @@ pub fn log_config(config: &config) { pub fn opt_str<'a>(maybestr: &'a Option<~str>) -> &'a str { match *maybestr { - option::None => "(none)", - option::Some(ref s) => { + None => "(none)", + Some(ref s) => { let s: &'a str = *s; s } @@ -161,7 +149,7 @@ pub fn opt_str2(maybestr: Option<~str>) -> ~str { } pub fn str_opt(maybestr: ~str) -> Option<~str> { - if maybestr != ~"(none)" { option::Some(maybestr) } else { option::None } + if maybestr != ~"(none)" { Some(maybestr) } else { None } } pub fn str_mode(s: ~str) -> mode { @@ -199,8 +187,8 @@ pub fn test_opts(config: &config) -> test::TestOpts { logfile: copy config.logfile, run_tests: true, run_benchmarks: false, - save_results: option::None, - compare_results: option::None + save_results: None, + compare_results: None } } @@ -268,7 +256,7 @@ pub fn make_test_name(config: &config, testfile: &Path) -> test::TestName { } pub fn make_test_closure(config: &config, testfile: &Path) -> test::TestFn { - use core::cell::Cell; + use std::cell::Cell; let config = Cell::new(copy *config); let testfile = Cell::new(testfile.to_str()); test::DynTestFn(|| { runtest::run(config.take(), testfile.take()) }) diff --git a/src/compiletest/errors.rs b/src/compiletest/errors.rs index 4649d4dfc3c4..780a917c019b 100644 --- a/src/compiletest/errors.rs +++ b/src/compiletest/errors.rs @@ -8,9 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - -use core::io; +use std::io; pub struct ExpectedError { line: uint, kind: ~str, msg: ~str } diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index ddb68d481167..9cd489f05766 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -8,13 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use common::config; use common; -use core::io; -use core::os; +use std::io; +use std::os; pub struct TestProps { // Lines that should be expected, in order, on standard out diff --git a/src/compiletest/procsrv.rs b/src/compiletest/procsrv.rs index 93fe258d167e..0e61b45d6199 100644 --- a/src/compiletest/procsrv.rs +++ b/src/compiletest/procsrv.rs @@ -8,11 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - -use core::os; -use core::run; -use core::str; +use std::os; +use std::run; +use std::str; #[cfg(target_os = "win32")] fn target_env(lib_path: &str, prog: &str) -> ~[(~str,~str)] { diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 715f6d91e09d..91016ba91fa5 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use common::mode_run_pass; use common::mode_run_fail; use common::mode_compile_fail; @@ -22,10 +20,10 @@ use procsrv; use util; use util::logv; -use core::io; -use core::os; -use core::uint; -use core::vec; +use std::io; +use std::os; +use std::uint; +use std::vec; pub fn run(config: config, testfile: ~str) { if config.verbose { @@ -79,8 +77,8 @@ fn run_rfail_test(config: &config, props: &TestProps, testfile: &Path) { }; // The value our Makefile configures valgrind to return on failure - static valgrind_err: int = 100; - if ProcRes.status == valgrind_err { + static VALGRIND_ERR: int = 100; + if ProcRes.status == VALGRIND_ERR { fatal_ProcRes(~"run-fail test isn't valgrind-clean!", &ProcRes); } @@ -102,8 +100,8 @@ fn run_rfail_test(config: &config, props: &TestProps, testfile: &Path) { fn check_correct_failure_status(ProcRes: &ProcRes) { // The value the rust runtime returns on failure - static rust_err: int = 101; - if ProcRes.status != rust_err { + static RUST_ERR: int = 101; + if ProcRes.status != RUST_ERR { fatal_ProcRes( fmt!("failure produced the wrong error code: %d", ProcRes.status), @@ -601,9 +599,8 @@ fn make_run_args(config: &config, _props: &TestProps, testfile: &Path) -> ProcArgs { // If we've got another tool to run under (valgrind), // then split apart its command - let toolargs = split_maybe_args(&config.runtool); - - let mut args = toolargs + [make_exe_name(config, testfile).to_str()]; + let mut args = split_maybe_args(&config.runtool); + args.push(make_exe_name(config, testfile).to_str()); let prog = args.shift(); return ProcArgs {prog: prog, args: args}; } diff --git a/src/compiletest/util.rs b/src/compiletest/util.rs index 26a62f8a5b22..5af469ff8417 100644 --- a/src/compiletest/util.rs +++ b/src/compiletest/util.rs @@ -8,12 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use common::config; -use core::io; -use core::os::getenv; +use std::io; +use std::os::getenv; pub fn make_new_path(path: &str) -> ~str { diff --git a/src/driver/driver.rs b/src/driver/driver.rs index 0f61ede4fc59..e81a3230e134 100644 --- a/src/driver/driver.rs +++ b/src/driver/driver.rs @@ -8,11 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[no_core]; -#[no_std]; - -extern mod core(name = "std", vers = "0.7"); - #[cfg(rustpkg)] extern mod this(name = "rustpkg"); diff --git a/src/etc/kate/rust.xml b/src/etc/kate/rust.xml index 63f1e50fcaf6..6aa953071476 100644 --- a/src/etc/kate/rust.xml +++ b/src/etc/kate/rust.xml @@ -7,7 +7,7 @@ ]> - + fn diff --git a/src/etc/local_stage0.sh b/src/etc/local_stage0.sh index 8d2fd887e3ff..3b70f9b967fb 100755 --- a/src/etc/local_stage0.sh +++ b/src/etc/local_stage0.sh @@ -43,7 +43,7 @@ fi cp ${PREFIX}/bin/rustc ${TARG_DIR}/stage0/bin/ cp ${PREFIX}/lib/rustc/${TARG_DIR}/${LIBDIR}/* ${TARG_DIR}/stage0/${LIBDIR}/ +cp ${PREFIX}/lib/libextra*${LIB_SUF} ${TARG_DIR}/stage0/${LIBDIR}/ cp ${PREFIX}/lib/librust*${LIB_SUF} ${TARG_DIR}/stage0/${LIBDIR}/ -cp ${PREFIX}/lib/libcore*${LIB_SUF} ${TARG_DIR}/stage0/${LIBDIR}/ cp ${PREFIX}/lib/libstd*${LIB_SUF} ${TARG_DIR}/stage0/${LIBDIR}/ cp ${PREFIX}/lib/libsyntax*${LIB_SUF} ${TARG_DIR}/stage0/${LIBDIR}/ diff --git a/src/etc/snapshot.py b/src/etc/snapshot.py index 608dbdcca5d2..36b00a3dedf2 100644 --- a/src/etc/snapshot.py +++ b/src/etc/snapshot.py @@ -1,6 +1,6 @@ # xfail-license -import re, os, sys, glob, tarfile, shutil, subprocess, tempfile +import re, os, sys, glob, tarfile, shutil, subprocess, tempfile, distutils.spawn try: import hashlib @@ -132,7 +132,13 @@ def local_rev_committer_date(): def get_url_to_file(u,f): # no security issue, just to stop partial download leaving a stale file tmpf = f + '.tmp' - returncode = subprocess.call(["curl", "-o", tmpf, u]) + + returncode = -1 + if distutils.spawn.find_executable("curl"): + returncode = subprocess.call(["curl", "-o", tmpf, u]) + elif distutils.spawn.find_executable("wget"): + returncode = subprocess.call(["wget", "-O", tmpf, u]) + if returncode != 0: os.unlink(tmpf) raise diff --git a/src/etc/unicode.py b/src/etc/unicode.py index 2a252f3f1f39..afcbc0a9859d 100755 --- a/src/etc/unicode.py +++ b/src/etc/unicode.py @@ -250,6 +250,7 @@ rf.write('''// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGH // The following code was generated by "src/etc/unicode.py" #[allow(missing_doc)]; +#[allow(non_uppercase_statics)]; ''') diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim index 25e44c62a8a7..f40bed8640dc 100644 --- a/src/etc/vim/syntax/rust.vim +++ b/src/etc/vim/syntax/rust.vim @@ -95,7 +95,7 @@ syn region rustDeriving start="deriving(" end=")" contains=rustTrait " Number literals syn match rustNumber display "\<[0-9][0-9_]*\>" syn match rustNumber display "\<[0-9][0-9_]*\(u\|u8\|u16\|u32\|u64\)\>" -syn match rustNumber display "\<[0-9][0-9_]*\(i8\|i16\|i32\|i64\)\>" +syn match rustNumber display "\<[0-9][0-9_]*\(i\|i8\|i16\|i32\|i64\)\>" syn match rustHexNumber display "\<0x[a-fA-F0-9_]\+\>" syn match rustHexNumber display "\<0x[a-fA-F0-9_]\+\(u\|u8\|u16\|u32\|u64\)\>" diff --git a/src/libextra/base64.rs b/src/libextra/base64.rs index a53a22ee831d..3c1fc72e9578 100644 --- a/src/libextra/base64.rs +++ b/src/libextra/base64.rs @@ -10,17 +10,37 @@ //! Base64 binary-to-text encoding - -use std::vec; - -/// A trait for converting a value to base64 encoding. -pub trait ToBase64 { - /// Converts the value of `self` to a base64 value, returning the owned - /// string - fn to_base64(&self) -> ~str; +/// Available encoding character sets +pub enum CharacterSet { + /// The standard character set (uses '+' and '/') + Standard, + /// The URL safe character set (uses '-' and '_') + UrlSafe } -static CHARS: [char, ..64] = [ +/// Contains configuration parameters for to_base64 +pub struct Config { + /// Character set to use + char_set: CharacterSet, + /// True to pad output with '=' characters + pad: bool, + /// Some(len) to wrap lines at len, None to disable line wrapping + line_length: Option +} + +/// Configuration for RFC 4648 standard base64 encoding +pub static STANDARD: Config = + Config {char_set: Standard, pad: true, line_length: None}; + +/// Configuration for RFC 4648 base64url encoding +pub static URL_SAFE: Config = + Config {char_set: UrlSafe, pad: false, line_length: None}; + +/// Configuration for RFC 2045 MIME base64 encoding +pub static MIME: Config = + Config {char_set: Standard, pad: true, line_length: Some(76)}; + +static STANDARD_CHARS: [char, ..64] = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', @@ -28,6 +48,21 @@ static CHARS: [char, ..64] = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' ]; +static URLSAFE_CHARS: [char, ..64] = [ + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' +]; + +/// A trait for converting a value to base64 encoding. +pub trait ToBase64 { + /// Converts the value of `self` to a base64 value following the specified + /// format configuration, returning the owned string. + fn to_base64(&self, config: Config) -> ~str; +} + impl<'self> ToBase64 for &'self [u8] { /** * Turn a vector of `u8` bytes into a base64 string. @@ -36,55 +71,81 @@ impl<'self> ToBase64 for &'self [u8] { * * ~~~ {.rust} * extern mod extra; - * use extra::base64::ToBase64; + * use extra::base64::{ToBase64, standard}; * * fn main () { - * let str = [52,32].to_base64(); + * let str = [52,32].to_base64(standard); * println(fmt!("%s", str)); * } * ~~~ */ - fn to_base64(&self) -> ~str { + fn to_base64(&self, config: Config) -> ~str { + let chars = match config.char_set { + Standard => STANDARD_CHARS, + UrlSafe => URLSAFE_CHARS + }; + let mut s = ~""; + let mut i = 0; + let mut cur_length = 0; let len = self.len(); - s.reserve(((len + 3u) / 4u) * 3u); + while i < len - (len % 3) { + match config.line_length { + Some(line_length) => + if cur_length >= line_length { + s.push_str("\r\n"); + cur_length = 0; + }, + None => () + } - let mut i = 0u; - - while i < len - (len % 3u) { - let n = (self[i] as uint) << 16u | - (self[i + 1u] as uint) << 8u | - (self[i + 2u] as uint); + let n = (self[i] as u32) << 16 | + (self[i + 1] as u32) << 8 | + (self[i + 2] as u32); // This 24-bit number gets separated into four 6-bit numbers. - s.push_char(CHARS[(n >> 18u) & 63u]); - s.push_char(CHARS[(n >> 12u) & 63u]); - s.push_char(CHARS[(n >> 6u) & 63u]); - s.push_char(CHARS[n & 63u]); + s.push_char(chars[(n >> 18) & 63]); + s.push_char(chars[(n >> 12) & 63]); + s.push_char(chars[(n >> 6 ) & 63]); + s.push_char(chars[n & 63]); - i += 3u; + cur_length += 4; + i += 3; + } + + if len % 3 != 0 { + match config.line_length { + Some(line_length) => + if cur_length >= line_length { + s.push_str("\r\n"); + }, + None => () + } } // Heh, would be cool if we knew this was exhaustive // (the dream of bounded integer types) match len % 3 { - 0 => (), - 1 => { - let n = (self[i] as uint) << 16u; - s.push_char(CHARS[(n >> 18u) & 63u]); - s.push_char(CHARS[(n >> 12u) & 63u]); - s.push_char('='); - s.push_char('='); - } - 2 => { - let n = (self[i] as uint) << 16u | - (self[i + 1u] as uint) << 8u; - s.push_char(CHARS[(n >> 18u) & 63u]); - s.push_char(CHARS[(n >> 12u) & 63u]); - s.push_char(CHARS[(n >> 6u) & 63u]); - s.push_char('='); - } - _ => fail!("Algebra is broken, please alert the math police") + 0 => (), + 1 => { + let n = (self[i] as u32) << 16; + s.push_char(chars[(n >> 18) & 63]); + s.push_char(chars[(n >> 12) & 63]); + if config.pad { + s.push_str("=="); + } + } + 2 => { + let n = (self[i] as u32) << 16 | + (self[i + 1u] as u32) << 8; + s.push_char(chars[(n >> 18) & 63]); + s.push_char(chars[(n >> 12) & 63]); + s.push_char(chars[(n >> 6 ) & 63]); + if config.pad { + s.push_char('='); + } + } + _ => fail!("Algebra is broken, please alert the math police") } s } @@ -99,23 +160,25 @@ impl<'self> ToBase64 for &'self str { * * ~~~ {.rust} * extern mod extra; - * use extra::base64::ToBase64; + * use extra::base64::{ToBase64, standard}; * * fn main () { - * let str = "Hello, World".to_base64(); + * let str = "Hello, World".to_base64(standard); * println(fmt!("%s",str)); * } * ~~~ * */ - fn to_base64(&self) -> ~str { - self.as_bytes().to_base64() + fn to_base64(&self, config: Config) -> ~str { + self.as_bytes().to_base64(config) } } -#[allow(missing_doc)] +/// A trait for converting from base64 encoded values. pub trait FromBase64 { - fn from_base64(&self) -> ~[u8]; + /// Converts the value of `self`, interpreted as base64 encoded data, into + /// an owned vector of bytes, returning the vector. + fn from_base64(&self) -> Result<~[u8], ~str>; } impl<'self> FromBase64 for &'self [u8] { @@ -127,69 +190,64 @@ impl<'self> FromBase64 for &'self [u8] { * * ~~~ {.rust} * extern mod extra; - * use extra::base64::ToBase64; - * use extra::base64::FromBase64; + * use extra::base64::{ToBase64, FromBase64, standard}; * * fn main () { - * let str = [52,32].to_base64(); + * let str = [52,32].to_base64(standard); * println(fmt!("%s", str)); * let bytes = str.from_base64(); * println(fmt!("%?",bytes)); * } * ~~~ */ - fn from_base64(&self) -> ~[u8] { - if self.len() % 4u != 0u { fail!("invalid base64 length"); } + fn from_base64(&self) -> Result<~[u8], ~str> { + let mut r = ~[]; + let mut buf: u32 = 0; + let mut modulus = 0; - let len = self.len(); - let mut padding = 0u; + let mut it = self.iter(); + for it.advance |&byte| { + let ch = byte as char; + let val = byte as u32; - if len != 0u { - if self[len - 1u] == '=' as u8 { padding += 1u; } - if self[len - 2u] == '=' as u8 { padding += 1u; } + match ch { + 'A'..'Z' => buf |= val - 0x41, + 'a'..'z' => buf |= val - 0x47, + '0'..'9' => buf |= val + 0x04, + '+'|'-' => buf |= 0x3E, + '/'|'_' => buf |= 0x3F, + '\r'|'\n' => loop, + '=' => break, + _ => return Err(~"Invalid Base64 character") + } + + buf <<= 6; + modulus += 1; + if modulus == 4 { + modulus = 0; + r.push((buf >> 22) as u8); + r.push((buf >> 14) as u8); + r.push((buf >> 6 ) as u8); + } } - let mut r = vec::with_capacity((len / 4u) * 3u - padding); - - let mut i = 0u; - while i < len { - let mut n = 0u; - - for 4u.times { - let ch = self[i] as char; - n <<= 6u; - - match ch { - 'A'..'Z' => n |= (ch as uint) - 0x41, - 'a'..'z' => n |= (ch as uint) - 0x47, - '0'..'9' => n |= (ch as uint) + 0x04, - '+' => n |= 0x3E, - '/' => n |= 0x3F, - '=' => { - match len - i { - 1u => { - r.push(((n >> 16u) & 0xFFu) as u8); - r.push(((n >> 8u ) & 0xFFu) as u8); - return copy r; - } - 2u => { - r.push(((n >> 10u) & 0xFFu) as u8); - return copy r; - } - _ => fail!("invalid base64 padding") - } - } - _ => fail!("invalid base64 character") - } - - i += 1u; - }; - - r.push(((n >> 16u) & 0xFFu) as u8); - r.push(((n >> 8u ) & 0xFFu) as u8); - r.push(((n ) & 0xFFu) as u8); + if !it.all(|&byte| {byte as char == '='}) { + return Err(~"Invalid Base64 character"); } - r + + match modulus { + 2 => { + r.push((buf >> 10) as u8); + } + 3 => { + r.push((buf >> 16) as u8); + r.push((buf >> 8 ) as u8); + } + 0 => (), + _ => return Err(~"Invalid Base64 length") + } + + Ok(r) } } @@ -199,7 +257,8 @@ impl<'self> FromBase64 for &'self str { * to the byte values it encodes. * * You can use the `from_bytes` function in `std::str` - * to turn a `[u8]` into a string with characters corresponding to those values. + * to turn a `[u8]` into a string with characters corresponding to those + * values. * * # Example * @@ -207,12 +266,11 @@ impl<'self> FromBase64 for &'self str { * * ~~~ {.rust} * extern mod extra; - * use extra::base64::ToBase64; - * use extra::base64::FromBase64; + * use extra::base64::{ToBase64, FromBase64, standard}; * use std::str; * * fn main () { - * let hello_str = "Hello, World".to_base64(); + * let hello_str = "Hello, World".to_base64(standard); * println(fmt!("%s",hello_str)); * let bytes = hello_str.from_base64(); * println(fmt!("%?",bytes)); @@ -221,32 +279,86 @@ impl<'self> FromBase64 for &'self str { * } * ~~~ */ - fn from_base64(&self) -> ~[u8] { + fn from_base64(&self) -> Result<~[u8], ~str> { self.as_bytes().from_base64() } } -#[cfg(test)] -mod tests { - #[test] - fn test_to_base64() { - assert_eq!("".to_base64(), ~""); - assert_eq!("f".to_base64(), ~"Zg=="); - assert_eq!("fo".to_base64(), ~"Zm8="); - assert_eq!("foo".to_base64(), ~"Zm9v"); - assert_eq!("foob".to_base64(), ~"Zm9vYg=="); - assert_eq!("fooba".to_base64(), ~"Zm9vYmE="); - assert_eq!("foobar".to_base64(), ~"Zm9vYmFy"); - } +#[test] +fn test_to_base64_basic() { + assert_eq!("".to_base64(STANDARD), ~""); + assert_eq!("f".to_base64(STANDARD), ~"Zg=="); + assert_eq!("fo".to_base64(STANDARD), ~"Zm8="); + assert_eq!("foo".to_base64(STANDARD), ~"Zm9v"); + assert_eq!("foob".to_base64(STANDARD), ~"Zm9vYg=="); + assert_eq!("fooba".to_base64(STANDARD), ~"Zm9vYmE="); + assert_eq!("foobar".to_base64(STANDARD), ~"Zm9vYmFy"); +} - #[test] - fn test_from_base64() { - assert_eq!("".from_base64(), "".as_bytes().to_owned()); - assert_eq!("Zg==".from_base64(), "f".as_bytes().to_owned()); - assert_eq!("Zm8=".from_base64(), "fo".as_bytes().to_owned()); - assert_eq!("Zm9v".from_base64(), "foo".as_bytes().to_owned()); - assert_eq!("Zm9vYg==".from_base64(), "foob".as_bytes().to_owned()); - assert_eq!("Zm9vYmE=".from_base64(), "fooba".as_bytes().to_owned()); - assert_eq!("Zm9vYmFy".from_base64(), "foobar".as_bytes().to_owned()); +#[test] +fn test_to_base64_line_break() { + assert!(![0u8, 1000].to_base64(Config {line_length: None, ..STANDARD}) + .contains("\r\n")); + assert_eq!("foobar".to_base64(Config {line_length: Some(4), ..STANDARD}), + ~"Zm9v\r\nYmFy"); +} + +#[test] +fn test_to_base64_padding() { + assert_eq!("f".to_base64(Config {pad: false, ..STANDARD}), ~"Zg"); + assert_eq!("fo".to_base64(Config {pad: false, ..STANDARD}), ~"Zm8"); +} + +#[test] +fn test_to_base64_url_safe() { + assert_eq!([251, 255].to_base64(URL_SAFE), ~"-_8"); + assert_eq!([251, 255].to_base64(STANDARD), ~"+/8="); +} + +#[test] +fn test_from_base64_basic() { + assert_eq!("".from_base64().get(), "".as_bytes().to_owned()); + assert_eq!("Zg==".from_base64().get(), "f".as_bytes().to_owned()); + assert_eq!("Zm8=".from_base64().get(), "fo".as_bytes().to_owned()); + assert_eq!("Zm9v".from_base64().get(), "foo".as_bytes().to_owned()); + assert_eq!("Zm9vYg==".from_base64().get(), "foob".as_bytes().to_owned()); + assert_eq!("Zm9vYmE=".from_base64().get(), "fooba".as_bytes().to_owned()); + assert_eq!("Zm9vYmFy".from_base64().get(), "foobar".as_bytes().to_owned()); +} + +#[test] +fn test_from_base64_newlines() { + assert_eq!("Zm9v\r\nYmFy".from_base64().get(), + "foobar".as_bytes().to_owned()); +} + +#[test] +fn test_from_base64_urlsafe() { + assert_eq!("-_8".from_base64().get(), "+/8=".from_base64().get()); +} + +#[test] +fn test_from_base64_invalid_char() { + assert!("Zm$=".from_base64().is_err()) + assert!("Zg==$".from_base64().is_err()); +} + +#[test] +fn test_from_base64_invalid_padding() { + assert!("Z===".from_base64().is_err()); +} + +#[test] +fn test_base64_random() { + use std::rand::{task_rng, random, RngUtil}; + use std::vec; + + for 1000.times { + let v: ~[u8] = do vec::build |push| { + for task_rng().gen_uint_range(1, 100).times { + push(random()); + } + }; + assert_eq!(v.to_base64(STANDARD).from_base64().get(), v); } } diff --git a/src/libextra/bitv.rs b/src/libextra/bitv.rs index 30541f832389..72b6e6dc6500 100644 --- a/src/libextra/bitv.rs +++ b/src/libextra/bitv.rs @@ -872,7 +872,7 @@ mod tests { use std::rand; use std::rand::Rng; - static bench_bits : uint = 1 << 14; + static BENCH_BITS : uint = 1 << 14; #[test] fn test_to_str() { @@ -1452,19 +1452,19 @@ mod tests { fn bench_big_bitv_big(b: &mut BenchHarness) { let mut r = rng(); let mut storage = ~[]; - storage.grow(bench_bits / uint::bits, &0); + storage.grow(BENCH_BITS / uint::bits, &0); let mut bitv = BigBitv::new(storage); do b.iter { - bitv.set((r.next() as uint) % bench_bits, true); + bitv.set((r.next() as uint) % BENCH_BITS, true); } } #[bench] fn bench_bitv_big(b: &mut BenchHarness) { let mut r = rng(); - let mut bitv = Bitv::new(bench_bits, false); + let mut bitv = Bitv::new(BENCH_BITS, false); do b.iter { - bitv.set((r.next() as uint) % bench_bits, true); + bitv.set((r.next() as uint) % BENCH_BITS, true); } } @@ -1491,14 +1491,14 @@ mod tests { let mut r = rng(); let mut bitv = BitvSet::new(); do b.iter { - bitv.insert((r.next() as uint) % bench_bits); + bitv.insert((r.next() as uint) % BENCH_BITS); } } #[bench] fn bench_bitv_big_union(b: &mut BenchHarness) { - let mut b1 = Bitv::new(bench_bits, false); - let b2 = Bitv::new(bench_bits, false); + let mut b1 = Bitv::new(BENCH_BITS, false); + let b2 = Bitv::new(BENCH_BITS, false); do b.iter { b1.union(&b2); } diff --git a/src/libextra/crypto/sha1.rs b/src/libextra/crypto/sha1.rs index 238e4a4d238d..0f2d44f57e34 100644 --- a/src/libextra/crypto/sha1.rs +++ b/src/libextra/crypto/sha1.rs @@ -240,7 +240,6 @@ impl Digest for Sha1 { #[cfg(test)] mod tests { - use std::vec; use digest::{Digest, DigestUtil}; use sha1::Sha1; @@ -337,7 +336,7 @@ mod tests { for tests.iter().advance |t| { (*sh).input_str(t.input); sh.result(out); - assert!(vec::eq(t.output, out)); + assert!(t.output.as_slice() == out); let out_str = (*sh).result_str(); assert_eq!(out_str.len(), 40); @@ -357,7 +356,7 @@ mod tests { left = left - take; } sh.result(out); - assert!(vec::eq(t.output, out)); + assert!(t.output.as_slice() == out); let out_str = (*sh).result_str(); assert_eq!(out_str.len(), 40); diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index f834860a4f70..36ebf295aaba 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -11,17 +11,17 @@ //! A double-ended queue implemented as a circular buffer use std::uint; -use std::util::replace; use std::vec; -use std::cast::transmute; +use std::iterator::FromIterator; -static initial_capacity: uint = 32u; // 2^5 +static INITIAL_CAPACITY: uint = 8u; // 2^3 +static MINIMUM_CAPACITY: uint = 2u; #[allow(missing_doc)] +#[deriving(Clone)] pub struct Deque { priv nelts: uint, priv lo: uint, - priv hi: uint, priv elts: ~[Option] } @@ -39,26 +39,36 @@ impl Mutable for Deque { for self.elts.mut_iter().advance |x| { *x = None } self.nelts = 0; self.lo = 0; - self.hi = 0; } } impl Deque { /// Create an empty Deque pub fn new() -> Deque { - Deque{nelts: 0, lo: 0, hi: 0, - elts: vec::from_fn(initial_capacity, |_| None)} + Deque::with_capacity(INITIAL_CAPACITY) + } + + /// Create an empty Deque with space for at least `n` elements. + pub fn with_capacity(n: uint) -> Deque { + Deque{nelts: 0, lo: 0, + elts: vec::from_fn(uint::max(MINIMUM_CAPACITY, n), |_| None)} } /// Return a reference to the first element in the deque /// /// Fails if the deque is empty - pub fn peek_front<'a>(&'a self) -> &'a T { get(self.elts, self.lo) } + pub fn peek_front<'a>(&'a self) -> &'a T { get(self.elts, self.raw_index(0)) } /// Return a reference to the last element in the deque /// /// Fails if the deque is empty - pub fn peek_back<'a>(&'a self) -> &'a T { get(self.elts, self.hi - 1u) } + pub fn peek_back<'a>(&'a self) -> &'a T { + if self.nelts > 0 { + get(self.elts, self.raw_index(self.nelts - 1)) + } else { + fail!("peek_back: empty deque"); + } + } /// Retrieve an element in the deque by index /// @@ -68,16 +78,6 @@ impl Deque { get(self.elts, idx) } - /// Iterate over the elements in the deque - pub fn each(&self, f: &fn(&T) -> bool) -> bool { - self.eachi(|_i, e| f(e)) - } - - /// Iterate over the elements in the deque by index - pub fn eachi(&self, f: &fn(uint, &T) -> bool) -> bool { - uint::range(0, self.nelts, |i| f(i, self.get(i as int))) - } - /// Remove and return the first element in the deque /// /// Fails if the deque is empty @@ -88,43 +88,39 @@ impl Deque { result } + /// Return index in underlying vec for a given logical element index + fn raw_index(&self, idx: uint) -> uint { + raw_index(self.lo, self.elts.len(), idx) + } + /// Remove and return the last element in the deque /// /// Fails if the deque is empty pub fn pop_back(&mut self) -> T { - if self.hi == 0u { - self.hi = self.elts.len() - 1u; - } else { self.hi -= 1u; } - let result = self.elts[self.hi].swap_unwrap(); - self.elts[self.hi] = None; - self.nelts -= 1u; - result + self.nelts -= 1; + let hi = self.raw_index(self.nelts); + self.elts[hi].swap_unwrap() } /// Prepend an element to the deque pub fn add_front(&mut self, t: T) { - let oldlo = self.lo; + if self.nelts == self.elts.len() { + grow(self.nelts, &mut self.lo, &mut self.elts); + } if self.lo == 0u { self.lo = self.elts.len() - 1u; } else { self.lo -= 1u; } - if self.lo == self.hi { - self.elts = grow(self.nelts, oldlo, self.elts); - self.lo = self.elts.len() - 1u; - self.hi = self.nelts; - } self.elts[self.lo] = Some(t); self.nelts += 1u; } /// Append an element to the deque pub fn add_back(&mut self, t: T) { - if self.lo == self.hi && self.nelts != 0u { - self.elts = grow(self.nelts, self.lo, self.elts); - self.lo = 0u; - self.hi = self.nelts; + if self.nelts == self.elts.len() { + grow(self.nelts, &mut self.lo, &mut self.elts); } - self.elts[self.hi] = Some(t); - self.hi = (self.hi + 1u) % self.elts.len(); + let hi = self.raw_index(self.nelts); + self.elts[hi] = Some(t); self.nelts += 1u; } @@ -155,42 +151,39 @@ impl Deque { /// 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 } + DequeIterator{index: 0, nelts: self.nelts, elts: self.elts, lo: self.lo} } /// 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 } + DequeMutIterator{index: 0, nelts: self.nelts, elts: self.elts, lo: self.lo} } /// 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 } + DequeRevIterator{index: self.nelts-1, nelts: self.nelts, elts: self.elts, + lo: self.lo} } /// 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 } + DequeMutRevIterator{index: self.nelts-1, nelts: self.nelts, elts: self.elts, + lo: self.lo} } } macro_rules! iterator { - (impl $name:ident -> $elem:ty, $step:expr) => { + (impl $name:ident -> $elem:ty, $getter:ident, $step:expr) => { impl<'self, T> Iterator<$elem> for $name<'self, T> { #[inline] fn next(&mut self) -> Option<$elem> { - if self.used >= self.nelts { + if self.nelts == 0 { 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 + let raw_index = raw_index(self.lo, self.elts.len(), self.index); + self.index += $step; + self.nelts -= 1; + Some(self.elts[raw_index]. $getter ()) } } } @@ -198,64 +191,115 @@ macro_rules! iterator { /// Deque iterator pub struct DequeIterator<'self, T> { - priv idx: uint, + priv lo: uint, priv nelts: uint, - priv used: uint, - priv vec: &'self [Option] + priv index: uint, + priv elts: &'self [Option], } -iterator!{impl DequeIterator -> &'self T, 1} +iterator!{impl DequeIterator -> &'self T, get_ref, 1} /// Deque reverse iterator pub struct DequeRevIterator<'self, T> { - priv idx: uint, + priv lo: uint, priv nelts: uint, - priv used: uint, - priv vec: &'self [Option] + priv index: uint, + priv elts: &'self [Option], } -iterator!{impl DequeRevIterator -> &'self T, -1} +iterator!{impl DequeRevIterator -> &'self T, get_ref, -1} /// Deque mutable iterator pub struct DequeMutIterator<'self, T> { - priv idx: uint, + priv lo: uint, priv nelts: uint, - priv used: uint, - priv vec: &'self mut [Option] - + priv index: uint, + priv elts: &'self mut [Option], } -iterator!{impl DequeMutIterator -> &'self mut T, 1} +iterator!{impl DequeMutIterator -> &'self mut T, get_mut_ref, 1} /// Deque mutable reverse iterator pub struct DequeMutRevIterator<'self, T> { - priv idx: uint, + priv lo: uint, priv nelts: uint, - priv used: uint, - priv vec: &'self mut [Option] + priv index: uint, + priv elts: &'self mut [Option], } -iterator!{impl DequeMutRevIterator -> &'self mut T, -1} +iterator!{impl DequeMutRevIterator -> &'self mut T, get_mut_ref, -1} /// Grow is only called on full elts, so nelts is also len(elts), unlike /// elsewhere. -fn grow(nelts: uint, lo: uint, elts: &mut [Option]) -> ~[Option] { +fn grow(nelts: uint, loptr: &mut uint, elts: &mut ~[Option]) { assert_eq!(nelts, elts.len()); - let mut rv = ~[]; + let lo = *loptr; + let newlen = nelts * 2; + elts.reserve(newlen); - do rv.grow_fn(nelts + 1) |i| { - replace(&mut elts[(lo + i) % nelts], None) + /* fill with None */ + for uint::range(elts.len(), elts.capacity()) |_| { + elts.push(None); } - rv + /* + Move the shortest half into the newly reserved area. + lo ---->| + nelts ----------->| + [o o o|o o o o o] + A [. . .|o o o o o o o o|. . . . .] + B [o o o|. . . . . . . .|o o o o o] + */ + + assert!(newlen - nelts/2 >= nelts); + if lo <= (nelts - lo) { // A + for uint::range(0, lo) |i| { + elts.swap(i, nelts + i); + } + } else { // B + for uint::range(lo, nelts) |i| { + elts.swap(i, newlen - nelts + i); + } + *loptr += newlen - nelts; + } } fn get<'r, T>(elts: &'r [Option], i: uint) -> &'r T { match elts[i] { Some(ref t) => t, _ => fail!() } } +/// Return index in underlying vec for a given logical element index +fn raw_index(lo: uint, len: uint, index: uint) -> uint { + if lo >= len - index { + lo + index - len + } else { + lo + index + } +} + +impl Eq for Deque { + fn eq(&self, other: &Deque) -> bool { + self.nelts == other.nelts && + self.iter().zip(other.iter()).all(|(a, b)| a.eq(b)) + } + fn ne(&self, other: &Deque) -> bool { + !self.eq(other) + } +} + +impl> FromIterator for Deque { + fn from_iterator(iterator: &mut T) -> Deque { + let mut deq = Deque::new(); + for iterator.advance |elt| { + deq.add_back(elt); + } + deq + } +} + #[cfg(test)] mod tests { use super::*; use std::cmp::Eq; use std::kinds::Copy; - use std::int; + use std::{int, uint}; + use extra::test; #[test] fn test_simple() { @@ -369,6 +413,61 @@ mod tests { assert_eq!(copy *deq.get(3), copy d); } + #[test] + fn test_add_front_grow() { + let mut deq = Deque::new(); + for int::range(0, 66) |i| { + deq.add_front(i); + } + assert_eq!(deq.len(), 66); + + for int::range(0, 66) |i| { + assert_eq!(*deq.get(i), 65 - i); + } + + let mut deq = Deque::new(); + for int::range(0, 66) |i| { + deq.add_back(i); + } + + for int::range(0, 66) |i| { + assert_eq!(*deq.get(i), i); + } + } + + #[bench] + fn bench_new(b: &mut test::BenchHarness) { + do b.iter { + let _ = Deque::new::(); + } + } + + #[bench] + fn bench_add_back(b: &mut test::BenchHarness) { + let mut deq = Deque::new(); + do b.iter { + deq.add_back(0); + } + } + + #[bench] + fn bench_add_front(b: &mut test::BenchHarness) { + let mut deq = Deque::new(); + do b.iter { + deq.add_front(0); + } + } + + #[bench] + fn bench_grow(b: &mut test::BenchHarness) { + let mut deq = Deque::new(); + do b.iter { + for 65.times { + deq.add_front(1); + } + } + } + #[deriving(Eq)] enum Taggy { One(int), Two(int, int), Three(int, int, int), } @@ -417,22 +516,13 @@ mod tests { } #[test] - fn test_eachi() { - let mut deq = Deque::new(); - deq.add_back(1); - deq.add_back(2); - deq.add_back(3); - - for deq.eachi |i, e| { - assert_eq!(*e, i + 1); - } - - deq.pop_front(); - - for deq.eachi |i, e| { - assert_eq!(*e, i + 2); - } - + fn test_with_capacity() { + let mut d = Deque::with_capacity(0); + d.add_back(1); + assert_eq!(d.len(), 1); + let mut d = Deque::with_capacity(50); + d.add_back(1); + assert_eq!(d.len(), 1); } #[test] @@ -462,6 +552,8 @@ mod tests { #[test] fn test_iter() { let mut d = Deque::new(); + assert_eq!(d.iter().next(), None); + for int::range(0,5) |i| { d.add_back(i); } @@ -476,6 +568,8 @@ mod tests { #[test] fn test_rev_iter() { let mut d = Deque::new(); + assert_eq!(d.rev_iter().next(), None); + for int::range(0,5) |i| { d.add_back(i); } @@ -486,4 +580,104 @@ mod tests { } assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0,&6,&7,&8]); } + + #[test] + fn test_mut_iter() { + let mut d = Deque::new(); + assert!(d.mut_iter().next().is_none()); + + for uint::range(0,3) |i| { + d.add_front(i); + } + + for d.mut_iter().enumerate().advance |(i, elt)| { + assert_eq!(*elt, 2 - i); + *elt = i; + } + + { + let mut it = d.mut_iter(); + assert_eq!(*it.next().unwrap(), 0); + assert_eq!(*it.next().unwrap(), 1); + assert_eq!(*it.next().unwrap(), 2); + assert!(it.next().is_none()); + } + } + + #[test] + fn test_mut_rev_iter() { + let mut d = Deque::new(); + assert!(d.mut_rev_iter().next().is_none()); + + for uint::range(0,3) |i| { + d.add_front(i); + } + + for d.mut_rev_iter().enumerate().advance |(i, elt)| { + assert_eq!(*elt, i); + *elt = i; + } + + { + let mut it = d.mut_rev_iter(); + assert_eq!(*it.next().unwrap(), 0); + assert_eq!(*it.next().unwrap(), 1); + assert_eq!(*it.next().unwrap(), 2); + assert!(it.next().is_none()); + } + } + + #[test] + fn test_from_iterator() { + use std::iterator; + let v = ~[1,2,3,4,5,6,7]; + let deq: Deque = v.iter().transform(|&x| x).collect(); + let u: ~[int] = deq.iter().transform(|&x| x).collect(); + assert_eq!(u, v); + + let mut seq = iterator::Counter::new(0u, 2).take_(256); + let deq: Deque = seq.collect(); + for deq.iter().enumerate().advance |(i, &x)| { + assert_eq!(2*i, x); + } + assert_eq!(deq.len(), 256); + } + + #[test] + fn test_clone() { + let mut d = Deque::new(); + d.add_front(17); + d.add_front(42); + d.add_back(137); + d.add_back(137); + assert_eq!(d.len(), 4u); + let mut e = d.clone(); + assert_eq!(e.len(), 4u); + while !d.is_empty() { + assert_eq!(d.pop_back(), e.pop_back()); + } + assert_eq!(d.len(), 0u); + assert_eq!(e.len(), 0u); + } + + #[test] + fn test_eq() { + let mut d = Deque::new(); + assert_eq!(&d, &Deque::with_capacity(0)); + d.add_front(137); + d.add_front(17); + d.add_front(42); + d.add_back(137); + let mut e = Deque::with_capacity(0); + e.add_back(42); + e.add_back(17); + e.add_back(137); + e.add_back(137); + assert_eq!(&e, &d); + e.pop_back(); + e.add_back(0); + assert!(e != d); + e.clear(); + assert_eq!(e, Deque::new()); + } } diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs index c79b012cfc5b..502e45e1d474 100644 --- a/src/libextra/ebml.rs +++ b/src/libextra/ebml.rs @@ -748,7 +748,7 @@ pub mod writer { // Set to true to generate more debugging in EBML code. // Totally lame approach. - static debug: bool = true; + static DEBUG: bool = true; impl Encoder { // used internally to emit things like the vector length and so on @@ -764,7 +764,7 @@ pub mod writer { // efficiency. When debugging, though, we can emit such // labels and then they will be checked by decoder to // try and check failures more quickly. - if debug { self.wr_tagged_str(EsLabel as uint, label) } + if DEBUG { self.wr_tagged_str(EsLabel as uint, label) } } } diff --git a/src/libextra/extra.rs b/src/libextra/extra.rs index 50c57b28d223..7bec1d600b43 100644 --- a/src/libextra/extra.rs +++ b/src/libextra/extra.rs @@ -21,7 +21,7 @@ Rust extras are part of the standard Rust distribution. */ #[link(name = "extra", - vers = "0.7", + vers = "0.8-pre", uuid = "122bed0b-c19b-4b82-b0b7-7ae8aead7297", url = "https://github.com/mozilla/rust/tree/master/src/libextra")]; @@ -40,10 +40,8 @@ pub mod uv_ll; // General io and system-services modules +#[path = "net/mod.rs"] pub mod net; -pub mod net_ip; -pub mod net_tcp; -pub mod net_url; // libuv modules pub mod uv; @@ -74,7 +72,6 @@ pub mod deque; pub mod fun_treemap; pub mod list; pub mod priority_queue; -pub mod rope; pub mod smallintmap; pub mod sort; diff --git a/src/libextra/flate.rs b/src/libextra/flate.rs index 92f9f834f52d..88c61e60d86b 100644 --- a/src/libextra/flate.rs +++ b/src/libextra/flate.rs @@ -39,20 +39,20 @@ pub mod rustrt { } } -static lz_none : c_int = 0x0; // Huffman-coding only. -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" +static LZ_NONE : c_int = 0x0; // Huffman-coding only. +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: &[u8]) -> ~[u8] { - do vec::as_imm_buf(bytes) |b, len| { + do bytes.as_imm_buf |b, len| { unsafe { let mut outsz : size_t = 0; let res = rustrt::tdefl_compress_mem_to_heap(b as *c_void, len as size_t, &mut outsz, - lz_norm); + LZ_NORM); assert!(res as int != 0); let out = vec::raw::from_buf_raw(res as *u8, outsz as uint); @@ -63,7 +63,7 @@ pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] { } pub fn inflate_bytes(bytes: &[u8]) -> ~[u8] { - do vec::as_imm_buf(bytes) |b, len| { + do bytes.as_imm_buf |b, len| { unsafe { let mut outsz : size_t = 0; let res = diff --git a/src/libextra/flatpipes.rs b/src/libextra/flatpipes.rs index e8bdc951ca4e..de0a988f94c8 100644 --- a/src/libextra/flatpipes.rs +++ b/src/libextra/flatpipes.rs @@ -55,7 +55,6 @@ 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, @@ -274,7 +273,7 @@ impl,P:BytePort> GenericPort for FlatPort { } }; - if vec::eq(command, CONTINUE) { + if CONTINUE.as_slice() == command { let msg_len = match self.byte_port.try_recv(size_of::()) { Some(bytes) => { io::u64_from_be_bytes(bytes, 0, size_of::()) @@ -931,7 +930,7 @@ mod test { fn test_try_recv_none3(loader: PortLoader

) { static CONTINUE: [u8, ..4] = [0xAA, 0xBB, 0xCC, 0xDD]; // The control word is followed by garbage - let bytes = CONTINUE.to_owned() + [0]; + let bytes = CONTINUE.to_owned() + &[0u8]; let port = loader(bytes); let res: Option = port.try_recv(); assert!(res.is_none()); @@ -955,7 +954,7 @@ mod test { 1, sys::size_of::()) |len_bytes| { len_bytes.to_owned() }; - let bytes = CONTINUE.to_owned() + len_bytes + [0, 0, 0, 0]; + let bytes = CONTINUE.to_owned() + len_bytes + &[0u8, 0, 0, 0]; let port = loader(bytes); diff --git a/src/libextra/getopts.rs b/src/libextra/getopts.rs index 1a494f36c646..c481fb8f5440 100644 --- a/src/libextra/getopts.rs +++ b/src/libextra/getopts.rs @@ -176,7 +176,7 @@ fn name_str(nm: &Name) -> ~str { } fn find_opt(opts: &[Opt], nm: Name) -> Option { - opts.iter().position_(|opt| opt.name == nm) + opts.iter().position(|opt| opt.name == nm) } /** diff --git a/src/libextra/iter.rs b/src/libextra/iter.rs new file mode 100644 index 000000000000..ad8dcf98317a --- /dev/null +++ b/src/libextra/iter.rs @@ -0,0 +1,328 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/*! Composable internal iterators + +Internal iterators are functions implementing the protocol used by the `for` loop. + +An internal iterator takes `fn(...) -> bool` as a parameter, with returning `false` used to signal +breaking out of iteration. The adaptors in the module work with any such iterator, not just ones +tied to specific traits. For example: + +~~~ {.rust} +println(iter::to_vec(|f| uint::range(0, 20, f)).to_str()); +~~~ + +An external iterator object implementing the interface in the `iterator` module can be used as an +internal iterator by calling the `advance` method. For example: + +~~~ {.rust} +let xs = [0u, 1, 2, 3, 4, 5]; +let ys = [30, 40, 50, 60]; +let mut it = xs.iter().chain(ys.iter()); +for it.advance |&x: &uint| { + println(x.to_str()); +} +~~~ + +Internal iterators provide a subset of the functionality of an external iterator. It's not possible +to interleave them to implement algorithms like `zip`, `union` and `merge`. However, they're often +much easier to implement. + +*/ + +use std::vec; +use std::cmp::Ord; +use std::option::{Option, Some, None}; +use std::num::{One, Zero}; +use std::ops::{Add, Mul}; + +#[allow(missing_doc)] +pub trait FromIter { + /// Build a container with elements from an internal iterator. + /// + /// # Example: + /// + /// ~~~ {.rust} + /// let xs = ~[1, 2, 3]; + /// let ys: ~[int] = do FromIter::from_iter |f| { xs.iter().advance(|x| f(*x)) }; + /// assert_eq!(xs, ys); + /// ~~~ + pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> Self; +} + +/** + * Return true if `predicate` is true for any values yielded by an internal iterator. + * + * Example: + * + * ~~~ {.rust} + * let xs = ~[1u, 2, 3, 4, 5]; + * assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f))); + * assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f))); + * ~~~ + */ +#[inline] +pub fn any(predicate: &fn(T) -> bool, + iter: &fn(f: &fn(T) -> bool) -> bool) -> bool { + for iter |x| { + if predicate(x) { + return true; + } + } + return false; +} + +/** + * Return true if `predicate` is true for all values yielded by an internal iterator. + * + * # Example: + * + * ~~~ {.rust} + * assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f))); + * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f))); + * ~~~ + */ +#[inline] +pub fn all(predicate: &fn(T) -> bool, + iter: &fn(f: &fn(T) -> bool) -> bool) -> bool { + // If we ever break, iter will return false, so this will only return true + // if predicate returns true for everything. + iter(|x| predicate(x)) +} + +/** + * Return the first element where `predicate` returns `true`. Return `None` if no element is found. + * + * # Example: + * + * ~~~ {.rust} + * let xs = ~[1u, 2, 3, 4, 5, 6]; + * assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.iter().advance(f)).unwrap(), 4); + * ~~~ + */ +#[inline] +pub fn find(predicate: &fn(&T) -> bool, + iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { + for iter |x| { + if predicate(&x) { + return Some(x); + } + } + None +} + +/** + * Return the largest item yielded by an iterator. Return `None` if the iterator is empty. + * + * # Example: + * + * ~~~ {.rust} + * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; + * assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &15); + * ~~~ + */ +#[inline] +pub fn max(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { + let mut result = None; + for iter |x| { + match result { + Some(ref mut y) => { + if x > *y { + *y = x; + } + } + None => result = Some(x) + } + } + result +} + +/** + * Return the smallest item yielded by an iterator. Return `None` if the iterator is empty. + * + * # Example: + * + * ~~~ {.rust} + * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; + * assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &-5); + * ~~~ + */ +#[inline] +pub fn min(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { + let mut result = None; + for iter |x| { + match result { + Some(ref mut y) => { + if x < *y { + *y = x; + } + } + None => result = Some(x) + } + } + result +} + +/** + * Reduce an iterator to an accumulated value. + * + * # Example: + * + * ~~~ {.rust} + * assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10); + * ~~~ + */ +#[inline] +pub fn fold(start: T, iter: &fn(f: &fn(U) -> bool) -> bool, f: &fn(&mut T, U)) -> T { + let mut result = start; + for iter |x| { + f(&mut result, x); + } + result +} + +/** + * Reduce an iterator to an accumulated value. + * + * `fold_ref` is usable in some generic functions where `fold` is too lenient to type-check, but it + * forces the iterator to yield borrowed pointers. + * + * # Example: + * + * ~~~ {.rust} + * fn product>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T { + * fold_ref(One::one::(), iter, |a, x| *a = a.mul(x)) + * } + * ~~~ + */ +#[inline] +pub fn fold_ref(start: T, iter: &fn(f: &fn(&U) -> bool) -> bool, f: &fn(&mut T, &U)) -> T { + let mut result = start; + for iter |x| { + f(&mut result, x); + } + result +} + +/** + * Return the sum of the items yielding by an iterator. + * + * # Example: + * + * ~~~ {.rust} + * let xs: ~[int] = ~[1, 2, 3, 4]; + * assert_eq!(do sum |f| { xs.iter().advance(f) }, 10); + * ~~~ + */ +#[inline] +pub fn sum>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T { + fold_ref(Zero::zero::(), iter, |a, x| *a = a.add(x)) +} + +/** + * Return the product of the items yielded by an iterator. + * + * # Example: + * + * ~~~ {.rust} + * let xs: ~[int] = ~[1, 2, 3, 4]; + * assert_eq!(do product |f| { xs.iter().advance(f) }, 24); + * ~~~ + */ +#[inline] +pub fn product>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T { + fold_ref(One::one::(), iter, |a, x| *a = a.mul(x)) +} + +impl FromIter for ~[T]{ + #[inline] + pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] { + let mut v = ~[]; + for iter |x| { v.push(x) } + v + } +} + +#[cfg(test)] +mod tests { + use super::*; + use prelude::*; + + use int; + use uint; + + #[test] + fn test_from_iter() { + let xs = ~[1, 2, 3]; + let ys: ~[int] = do FromIter::from_iter |f| { xs.iter().advance(|x| f(*x)) }; + assert_eq!(xs, ys); + } + + #[test] + fn test_any() { + let xs = ~[1u, 2, 3, 4, 5]; + assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f))); + assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f))); + } + + #[test] + fn test_all() { + assert!(all(|x: uint| x < 6, |f| uint::range(1, 6, f))); + assert!(!all(|x: uint| x < 5, |f| uint::range(1, 6, f))); + } + + #[test] + fn test_find() { + let xs = ~[1u, 2, 3, 4, 5, 6]; + assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.iter().advance(f)).unwrap(), 4); + } + + #[test] + fn test_max() { + let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; + assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &15); + } + + #[test] + fn test_min() { + let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; + assert_eq!(min(|f| xs.iter().advance(f)).unwrap(), &-5); + } + + #[test] + fn test_fold() { + assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10); + } + + #[test] + fn test_sum() { + let xs: ~[int] = ~[1, 2, 3, 4]; + assert_eq!(do sum |f| { xs.iter().advance(f) }, 10); + } + + #[test] + fn test_empty_sum() { + let xs: ~[int] = ~[]; + assert_eq!(do sum |f| { xs.iter().advance(f) }, 0); + } + + #[test] + fn test_product() { + let xs: ~[int] = ~[1, 2, 3, 4]; + assert_eq!(do product |f| { xs.iter().advance(f) }, 24); + } + + #[test] + fn test_empty_product() { + let xs: ~[int] = ~[]; + assert_eq!(do product |f| { xs.iter().advance(f) }, 1); + } +} diff --git a/src/libextra/json.rs b/src/libextra/json.rs index 210921aa3d76..67ffd53a0e80 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -24,7 +24,6 @@ use std::io::{WriterUtil, ReaderUtil}; use std::io; use std::str; use std::to_str; -use std::vec; use serialize::Encodable; use serialize; @@ -482,9 +481,13 @@ pub fn to_pretty_str(json: &Json) -> ~str { io::with_str_writer(|wr| to_pretty_writer(wr, json)) } +static BUF_SIZE : uint = 64000; + #[allow(missing_doc)] pub struct Parser { priv rdr: @io::Reader, + priv buf: ~[char], + priv buf_idx: uint, priv ch: char, priv line: uint, priv col: uint, @@ -492,12 +495,16 @@ pub struct Parser { /// Decode a json value from an io::reader pub fn Parser(rdr: @io::Reader) -> Parser { - Parser { + let mut p = Parser { rdr: rdr, - ch: rdr.read_char(), + buf: rdr.read_chars(BUF_SIZE), + buf_idx: 0, + ch: 0 as char, line: 1, - col: 1, - } + col: 0, + }; + p.bump(); + p } impl Parser { @@ -522,13 +529,26 @@ impl Parser { fn eof(&self) -> bool { self.ch == -1 as char } fn bump(&mut self) { - self.ch = self.rdr.read_char(); + if self.eof() { + return; + } + + self.col += 1u; + + if self.buf_idx >= self.buf.len() { + self.buf = self.rdr.read_chars(BUF_SIZE); + if self.buf.len() == 0 { + self.ch = -1 as char; + return; + } + self.buf_idx = 0; + } + self.ch = self.buf[self.buf_idx]; + self.buf_idx += 1; if self.ch == '\n' { self.line += 1u; self.col = 1u; - } else { - self.col += 1u; } } @@ -941,7 +961,7 @@ impl serialize::Decoder for Decoder { let name = match self.stack.pop() { String(s) => s, List(list) => { - do vec::consume_reverse(list) |_i, v| { + for list.consume_rev_iter().advance |v| { self.stack.push(v); } match self.stack.pop() { @@ -951,7 +971,7 @@ impl serialize::Decoder for Decoder { } ref json => fail!("invalid variant: %?", *json), }; - let idx = match names.iter().position_(|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), }; @@ -1059,7 +1079,7 @@ impl serialize::Decoder for Decoder { let len = match self.stack.pop() { List(list) => { let len = list.len(); - do vec::consume_reverse(list) |_i, v| { + for list.consume_rev_iter().advance |v| { self.stack.push(v); } len diff --git a/src/libextra/net_ip.rs b/src/libextra/net/ip.rs similarity index 94% rename from src/libextra/net_ip.rs rename to src/libextra/net/ip.rs index d18aac684813..6876b3510b6c 100644 --- a/src/libextra/net_ip.rs +++ b/src/libextra/net/ip.rs @@ -22,20 +22,20 @@ use std::str; use iotask = uv::iotask::IoTask; use interact = uv::iotask::interact; -use sockaddr_in = super::uv_ll::sockaddr_in; -use sockaddr_in6 = super::uv_ll::sockaddr_in6; -use addrinfo = super::uv_ll::addrinfo; -use uv_getaddrinfo_t = super::uv_ll::uv_getaddrinfo_t; -use uv_ip4_name = super::uv_ll::ip4_name; -use uv_ip4_port = super::uv_ll::ip4_port; -use uv_ip6_name = super::uv_ll::ip6_name; -use uv_ip6_port = super::uv_ll::ip6_port; -use uv_getaddrinfo = super::uv_ll::getaddrinfo; -use uv_freeaddrinfo = super::uv_ll::freeaddrinfo; -use create_uv_getaddrinfo_t = super::uv_ll::getaddrinfo_t; -use set_data_for_req = super::uv_ll::set_data_for_req; -use get_data_for_req = super::uv_ll::get_data_for_req; -use ll = super::uv_ll; +use sockaddr_in = uv_ll::sockaddr_in; +use sockaddr_in6 = uv_ll::sockaddr_in6; +use addrinfo = uv_ll::addrinfo; +use uv_getaddrinfo_t = uv_ll::uv_getaddrinfo_t; +use uv_ip4_name = uv_ll::ip4_name; +use uv_ip4_port = uv_ll::ip4_port; +use uv_ip6_name = uv_ll::ip6_name; +use uv_ip6_port = uv_ll::ip6_port; +use uv_getaddrinfo = uv_ll::getaddrinfo; +use uv_freeaddrinfo = uv_ll::freeaddrinfo; +use create_uv_getaddrinfo_t = uv_ll::getaddrinfo_t; +use set_data_for_req = uv_ll::set_data_for_req; +use get_data_for_req = uv_ll::get_data_for_req; +use ll = uv_ll; /// An IP address pub enum IpAddr { @@ -203,7 +203,7 @@ pub mod v4 { }).collect(); if parts.len() != 4 { Err(fmt!("'%s' doesn't have 4 parts", ip)) - } else if parts.iter().any_(|x| *x == 256u) { + } else if parts.iter().any(|x| *x == 256u) { Err(fmt!("invalid octal in addr '%s'", ip)) } else { Ok(Ipv4Rep { @@ -363,9 +363,9 @@ extern fn get_addr_cb(handle: *uv_getaddrinfo_t, #[cfg(test)] mod test { - use net_ip::*; - use net_ip::v4; - use net_ip::v6; + use net::ip::*; + use net::ip::v4; + use net::ip::v6; use uv; use std::result; diff --git a/src/libextra/net.rs b/src/libextra/net/mod.rs similarity index 86% rename from src/libextra/net.rs rename to src/libextra/net/mod.rs index ca1cc1235961..463260bd3dcd 100644 --- a/src/libextra/net.rs +++ b/src/libextra/net/mod.rs @@ -13,13 +13,13 @@ Top-level module for network-related functionality. Basically, including this module gives you: -* `net_tcp` -* `net_ip` -* `net_url` +* `tcp` +* `ip` +* `url` See each of those three modules for documentation on what they do. */ -pub use tcp = net_tcp; -pub use ip = net_ip; -pub use url = net_url; +pub mod tcp; +pub mod ip; +pub mod url; diff --git a/src/libextra/net_tcp.rs b/src/libextra/net/tcp.rs similarity index 99% rename from src/libextra/net_tcp.rs rename to src/libextra/net/tcp.rs index 6a22950ec04b..e0ed313bc026 100644 --- a/src/libextra/net_tcp.rs +++ b/src/libextra/net/tcp.rs @@ -16,7 +16,7 @@ use future; use future_spawn = future::spawn; -use ip = net_ip; +use ip = net::ip; use uv; use uv::iotask; use uv::iotask::IoTask; diff --git a/src/libextra/net_url.rs b/src/libextra/net/url.rs similarity index 99% rename from src/libextra/net_url.rs rename to src/libextra/net/url.rs index 9ac58efe7930..307f75dc98be 100644 --- a/src/libextra/net_url.rs +++ b/src/libextra/net/url.rs @@ -522,7 +522,7 @@ fn get_authority(rawurl: &str) -> let host_is_end_plus_one: &fn() -> bool = || { let xs = ['?', '#', '/']; end+1 == len - && !xs.iter().any_(|x| *x == (rawurl[end] as char)) + && !xs.iter().any(|x| *x == (rawurl[end] as char)) }; // finish up @@ -800,7 +800,7 @@ fn test_get_path() { #[cfg(test)] mod tests { - use net_url::*; + use net::url::*; use std::hashmap::HashMap; diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index 9422ad0c9f2e..a0b95924e09d 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -17,6 +17,7 @@ A BigInt is a combination of BigUint and Sign. */ #[allow(missing_doc)]; +#[allow(non_uppercase_statics)]; use std::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; use std::int; @@ -206,7 +207,7 @@ impl Add for BigUint { let new_len = uint::max(self.data.len(), other.data.len()); let mut carry = 0; - let sum = do vec::from_fn(new_len) |i| { + let mut sum = do vec::from_fn(new_len) |i| { let ai = if i < self.data.len() { self.data[i] } else { 0 }; let bi = if i < other.data.len() { other.data[i] } else { 0 }; let (hi, lo) = BigDigit::from_uint( @@ -215,8 +216,8 @@ impl Add for BigUint { carry = hi; lo }; - if carry == 0 { return BigUint::new(sum) }; - return BigUint::new(sum + [carry]); + if carry != 0 { sum.push(carry); } + return BigUint::new(sum); } } @@ -283,15 +284,15 @@ impl Mul for BigUint { if n == 1 { return copy *a; } let mut carry = 0; - let prod = do a.data.iter().transform |ai| { + let mut 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]); + if carry != 0 { prod.push(carry); } + return BigUint::new(prod); } @@ -519,10 +520,12 @@ impl ToStrRadix for BigUint { fn fill_concat(v: &[BigDigit], radix: uint, l: uint) -> ~str { if v.is_empty() { return ~"0" } - let s = vec::reversed(v).map(|n| { - let s = uint::to_str_radix(*n as uint, radix); - str::from_chars(vec::from_elem(l - s.len(), '0')) + s - }).concat(); + let mut s = str::with_capacity(v.len() * l); + for v.rev_iter().advance |n| { + let ss = uint::to_str_radix(*n as uint, radix); + s.push_str("0".repeat(l - ss.len())); + s.push_str(ss); + } s.trim_left_chars(&'0').to_owned() } } @@ -618,15 +621,15 @@ impl BigUint { if n_bits == 0 || self.is_zero() { return copy *self; } let mut carry = 0; - let shifted = do self.data.iter().transform |elem| { + let mut 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]); + if carry != 0 { shifted.push(carry); } + return BigUint::new(shifted); } @@ -1628,7 +1631,6 @@ mod bigint_tests { use std::int; use std::num::{IntConvertible, Zero, One, FromStrRadix}; use std::uint; - use std::vec; #[test] fn test_from_biguint() { @@ -1645,9 +1647,11 @@ mod bigint_tests { #[test] fn test_cmp() { - let vs = [ &[2], &[1, 1], &[2, 1], &[1, 1, 1] ]; - let mut nums = vec::reversed(vs) - .map(|s| BigInt::from_slice(Minus, *s)); + let vs = [ &[2 as BigDigit], &[1, 1], &[2, 1], &[1, 1, 1] ]; + let mut nums = ~[]; + for vs.rev_iter().advance |s| { + nums.push(BigInt::from_slice(Minus, *s)); + } nums.push(Zero::zero()); nums.push_all_move(vs.map(|s| BigInt::from_slice(Plus, *s))); diff --git a/src/libextra/num/complex.rs b/src/libextra/num/complex.rs index 915523443fbc..00224f8b06d9 100644 --- a/src/libextra/num/complex.rs +++ b/src/libextra/num/complex.rs @@ -191,6 +191,8 @@ impl ToStrRadix for Cmplx { #[cfg(test)] mod test { + #[allow(non_uppercase_statics)]; + use super::*; use std::num::{Zero,One,Real}; diff --git a/src/libextra/par.rs b/src/libextra/par.rs index 2878a3ee1221..d737698cfe2c 100644 --- a/src/libextra/par.rs +++ b/src/libextra/par.rs @@ -20,10 +20,10 @@ use future_spawn = future::spawn; * The maximum number of tasks this module will spawn for a single * operation. */ -static max_tasks : uint = 32u; +static MAX_TASKS : uint = 32u; /// The minimum number of elements each task will process. -static min_granularity : uint = 1024u; +static MIN_GRANULARITY : uint = 1024u; /** * An internal helper to map a function over a large vector and @@ -38,13 +38,13 @@ fn map_slices( -> ~[B] { let len = xs.len(); - if len < min_granularity { + if len < MIN_GRANULARITY { info!("small slice"); // This is a small vector, fall back on the normal map. ~[f()(0u, xs)] } else { - let num_tasks = uint::min(max_tasks, len / min_granularity); + let num_tasks = uint::min(MAX_TASKS, len / MIN_GRANULARITY); let items_per_task = len / num_tasks; @@ -53,7 +53,7 @@ fn map_slices( info!("spawning tasks"); while base < len { let end = uint::min(len, base + items_per_task); - do vec::as_imm_buf(xs) |p, _len| { + do xs.as_imm_buf |p, _len| { let f = f(); let base = base; let f = do future_spawn() || { @@ -78,11 +78,10 @@ fn map_slices( info!("num_tasks: %?", (num_tasks, futures.len())); assert_eq!(num_tasks, futures.len()); - let r = do vec::map_consume(futures) |ys| { + do futures.consume_iter().transform |ys| { let mut ys = ys; ys.get() - }; - r + }.collect() } } @@ -137,8 +136,8 @@ pub fn any( fn_factory: &fn() -> ~fn(&A) -> bool) -> bool { let mapped = map_slices(xs, || { let f = fn_factory(); - let result: ~fn(uint, &[A]) -> bool = |_, slice| slice.iter().any_(f); + let result: ~fn(uint, &[A]) -> bool = |_, slice| slice.iter().any(f); result }); - mapped.iter().any_(|&x| x) + mapped.iter().any(|&x| x) } diff --git a/src/libextra/priority_queue.rs b/src/libextra/priority_queue.rs index 3d1ca4a9818b..1f7ba9f65303 100644 --- a/src/libextra/priority_queue.rs +++ b/src/libextra/priority_queue.rs @@ -186,6 +186,9 @@ pub struct PriorityQueueIterator <'self, T> { impl<'self, T> Iterator<&'self T> for PriorityQueueIterator<'self, T> { #[inline] fn next(&mut self) -> Option<(&'self T)> { self.iter.next() } + + #[inline] + fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } } #[cfg(test)] diff --git a/src/libextra/rope.rs b/src/libextra/rope.rs deleted file mode 100644 index 8374c1a86e31..000000000000 --- a/src/libextra/rope.rs +++ /dev/null @@ -1,1442 +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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/*! - * High-level text containers. - * - * Ropes are a high-level representation of text that offers - * much better performance than strings for common operations, - * and generally reduce memory allocations and copies, while only - * entailing a small degradation of less common operations. - * - * More precisely, where a string is represented as a memory buffer, - * a rope is a tree structure whose leaves are slices of immutable - * strings. Therefore, concatenation, appending, prepending, substrings, - * etc. are operations that require only trivial tree manipulation, - * generally without having to copy memory. In addition, the tree - * structure of ropes makes them suitable as a form of index to speed-up - * access to Unicode characters by index in long chunks of text. - * - * The following operations are algorithmically faster in ropes: - * - * * extracting a subrope is logarithmic (linear in strings); - * * appending/prepending is near-constant time (linear in strings); - * * concatenation is near-constant time (linear in strings); - * * char length is constant-time (linear in strings); - * * access to a character by index is logarithmic (linear in strings); - */ - -#[allow(missing_doc)]; - - -use std::uint; -use std::vec; -use std::str; - -/// The type of ropes. -pub type Rope = node::Root; - -/* - Section: Creating a rope - */ - -/// Create an empty rope -pub fn empty() -> Rope { - return node::Empty; -} - -/** - * Adopt a string as a rope. - * - * # Arguments - * - * * str - A valid string. - * - * # Return value - * - * A rope representing the same string as `str`. Depending of the length - * of `str`, this rope may be empty, flat or complex. - * - * # Performance notes - * - * * this operation does not copy the string; - * * the function runs in linear time. - */ -pub fn of_str(str: @~str) -> Rope { - return of_substr(str, 0u, str.len()); -} - -/** - * As `of_str` but for a substring. - * - * # Arguments - * * byte_offset - The offset of `str` at which the rope starts. - * * byte_len - The number of bytes of `str` to use. - * - * # Return value - * - * A rope representing the same string as `str.slice(byte_offset, - * byte_offset + byte_len)`. Depending on `byte_len`, this rope may - * be empty, flat or complex. - * - * # Performance note - * - * This operation does not copy the substring. - * - * # Safety notes - * - * * this function does _not_ check the validity of the substring; - * * this function fails if `byte_offset` or `byte_len` do not match `str`. - */ -pub fn of_substr(str: @~str, byte_offset: uint, byte_len: uint) -> Rope { - if byte_len == 0u { return node::Empty; } - if byte_offset + byte_len > str.len() { fail!(); } - return node::Content(node::of_substr(str, byte_offset, byte_len)); -} - -/* -Section: Adding things to a rope - */ - -/** - * Add one char to the end of the rope - * - * # Performance note - * - * * this function executes in near-constant time - */ -pub fn append_char(rope: Rope, char: char) -> Rope { - return append_str(rope, @str::from_chars([char])); -} - -/** - * Add one string to the end of the rope - * - * # Performance note - * - * * this function executes in near-linear time - */ -pub fn append_str(rope: Rope, str: @~str) -> Rope { - return append_rope(rope, of_str(str)) -} - -/** - * Add one char to the beginning of the rope - * - * # Performance note - * * this function executes in near-constant time - */ -pub fn prepend_char(rope: Rope, char: char) -> Rope { - return prepend_str(rope, @str::from_chars([char])); -} - -/** - * Add one string to the beginning of the rope - * - * # Performance note - * * this function executes in near-linear time - */ -pub fn prepend_str(rope: Rope, str: @~str) -> Rope { - return append_rope(of_str(str), rope) -} - -/// Concatenate two ropes -pub fn append_rope(left: Rope, right: Rope) -> Rope { - match (left) { - node::Empty => return right, - node::Content(left_content) => { - match (right) { - node::Empty => return left, - node::Content(right_content) => { - return node::Content(node::concat2(left_content, right_content)); - } - } - } - } -} - -/** - * Concatenate many ropes. - * - * If the ropes are balanced initially and have the same height, the resulting - * rope remains balanced. However, this function does not take any further - * measure to ensure that the result is balanced. - */ -pub fn concat(v: ~[Rope]) -> Rope { - //Copy `v` into a mut vector - let mut len = v.len(); - if len == 0u { return node::Empty; } - let mut ropes = vec::from_elem(len, v[0]); - for uint::range(1u, len) |i| { - ropes[i] = v[i]; - } - - //Merge progresively - while len > 1u { - for uint::range(0u, len/2u) |i| { - ropes[i] = append_rope(ropes[2u*i], ropes[2u*i+1u]); - } - if len%2u != 0u { - ropes[len/2u] = ropes[len - 1u]; - len = len/2u + 1u; - } else { - len = len/2u; - } - } - - //Return final rope - return ropes[0]; -} - - -/* -Section: Keeping ropes healthy - */ - - -/** - * Balance a rope. - * - * # Return value - * - * A copy of the rope in which small nodes have been grouped in memory, - * and with a reduced height. - * - * If you perform numerous rope concatenations, it is generally a good idea - * to rebalance your rope at some point, before using it for other purposes. - */ -pub fn bal(rope:Rope) -> Rope { - match (rope) { - node::Empty => return rope, - node::Content(x) => match (node::bal(x)) { - None => rope, - Some(y) => node::Content(y) - } - } -} - -/* -Section: Transforming ropes - */ - - -/** - * Extract a subrope from a rope. - * - * # Performance note - * - * * on a balanced rope, this operation takes algorithmic time; - * * this operation does not involve any copying - * - * # Safety note - * - * * this function fails if char_offset/char_len do not represent - * valid positions in rope - */ -pub fn sub_chars(rope: Rope, char_offset: uint, char_len: uint) -> Rope { - if char_len == 0u { return node::Empty; } - match (rope) { - node::Empty => fail!(), - node::Content(node) => if char_len > node::char_len(node) { - fail!() - } else { - return node::Content(node::sub_chars(node, char_offset, char_len)) - } - } -} - -/** - * Extract a subrope from a rope. - * - * # Performance note - * - * * on a balanced rope, this operation takes algorithmic time; - * * this operation does not involve any copying - * - * # Safety note - * - * * this function fails if byte_offset/byte_len do not represent - * valid positions in rope - */ -pub fn sub_bytes(rope: Rope, byte_offset: uint, byte_len: uint) -> Rope { - if byte_len == 0u { return node::Empty; } - match (rope) { - node::Empty => fail!(), - node::Content(node) =>if byte_len > node::byte_len(node) { - fail!() - } else { - return node::Content(node::sub_bytes(node, byte_offset, byte_len)) - } - } -} - -/* -Section: Comparing ropes - */ - -/** - * Compare two ropes by Unicode lexicographical order. - * - * This function compares only the contents of the rope, not their structure. - * - * # Return value - * - * A negative value if `left < right`, 0 if eq(left, right) or a positive - * value if `left > right` - */ -pub fn cmp(left: Rope, right: Rope) -> int { - match ((left, right)) { - (node::Empty, node::Empty) => return 0, - (node::Empty, _) => return -1, - (_, node::Empty) => return 1, - (node::Content(a), node::Content(b)) => { - return node::cmp(a, b); - } - } -} - -/** - * Returns `true` if both ropes have the same content (regardless of - * their structure), `false` otherwise - */ -pub fn eq(left: Rope, right: Rope) -> bool { - return cmp(left, right) == 0; -} - -/** - * # Arguments - * - * * left - an arbitrary rope - * * right - an arbitrary rope - * - * # Return value - * - * `true` if `left <= right` in lexicographical order (regardless of their - * structure), `false` otherwise - */ -pub fn le(left: Rope, right: Rope) -> bool { - return cmp(left, right) <= 0; -} - -/** - * # Arguments - * - * * left - an arbitrary rope - * * right - an arbitrary rope - * - * # Return value - * - * `true` if `left < right` in lexicographical order (regardless of their - * structure), `false` otherwise - */ -pub fn lt(left: Rope, right: Rope) -> bool { - return cmp(left, right) < 0; -} - -/** - * # Arguments - * - * * left - an arbitrary rope - * * right - an arbitrary rope - * - * # Return value - * - * `true` if `left >= right` in lexicographical order (regardless of their - * structure), `false` otherwise - */ -pub fn ge(left: Rope, right: Rope) -> bool { - return cmp(left, right) >= 0; -} - -/** - * # Arguments - * - * * left - an arbitrary rope - * * right - an arbitrary rope - * - * # Return value - * - * `true` if `left > right` in lexicographical order (regardless of their - * structure), `false` otherwise - */ -pub fn gt(left: Rope, right: Rope) -> bool { - return cmp(left, right) > 0; -} - -/* -Section: Iterating - */ - -/** - * Loop through a rope, char by char - * - * While other mechanisms are available, this is generally the best manner - * of looping through the contents of a rope char by char. If you prefer a - * loop that iterates through the contents string by string (e.g. to print - * the contents of the rope or output it to the system), however, - * you should rather use `traverse_components`. - * - * # Arguments - * - * * rope - A rope to traverse. It may be empty. - * * it - A block to execute with each consecutive character of the rope. - * Return `true` to continue, `false` to stop. - * - * # Return value - * - * `true` If execution proceeded correctly, `false` if it was interrupted, - * that is if `it` returned `false` at any point. - */ -pub fn loop_chars(rope: Rope, it: &fn(c: char) -> bool) -> bool { - match (rope) { - node::Empty => return true, - node::Content(x) => return node::loop_chars(x, it) - } -} - -/** - * Loop through a rope, char by char, until the end. - * - * # Arguments - * * rope - A rope to traverse. It may be empty - * * it - A block to execute with each consecutive character of the rope. - */ -pub fn iter_chars(rope: Rope, it: &fn(char)) { - do loop_chars(rope) |x| { - it(x); - true - }; -} - -/** - * Loop through a rope, string by string - * - * While other mechanisms are available, this is generally the best manner of - * looping through the contents of a rope string by string, which may be - * useful e.g. to print strings as you see them (without having to copy their - * contents into a new string), to send them to then network, to write them to - * a file, etc.. If you prefer a loop that iterates through the contents - * char by char (e.g. to search for a char), however, you should rather - * use `traverse`. - * - * # Arguments - * - * * rope - A rope to traverse. It may be empty - * * it - A block to execute with each consecutive string component of the - * rope. Return `true` to continue, `false` to stop - * - * # Return value - * - * `true` If execution proceeded correctly, `false` if it was interrupted, - * that is if `it` returned `false` at any point. - */ -pub fn loop_leaves(rope: Rope, it: &fn(node::Leaf) -> bool) -> bool{ - match (rope) { - node::Empty => return true, - node::Content(x) => return node::loop_leaves(x, it) - } -} - -pub mod iterator { - pub mod leaf { - - use rope::{Rope, node}; - - pub fn start(rope: Rope) -> node::leaf_iterator::T { - match (rope) { - node::Empty => return node::leaf_iterator::empty(), - node::Content(x) => return node::leaf_iterator::start(x) - } - } - pub fn next(it: &mut node::leaf_iterator::T) -> Option { - return node::leaf_iterator::next(it); - } - } - pub mod char { - - use rope::{Rope, node}; - - pub fn start(rope: Rope) -> node::char_iterator::T { - match (rope) { - node::Empty => return node::char_iterator::empty(), - node::Content(x) => return node::char_iterator::start(x) - } - } - pub fn next(it: &mut node::char_iterator::T) -> Option { - return node::char_iterator::next(it) - } - } -} - -/* - Section: Rope properties - */ - -/** - * Returns the height of the rope. - * - * The height of the rope is a bound on the number of operations which - * must be performed during a character access before finding the leaf in - * which a character is contained. - * - * # Performance note - * - * Constant time. - */ -pub fn height(rope: Rope) -> uint { - match (rope) { - node::Empty => return 0u, - node::Content(x) => return node::height(x) - } -} - - - -/** - * The number of character in the rope - * - * # Performance note - * - * Constant time. - */ -pub fn char_len(rope: Rope) -> uint { - match (rope) { - node::Empty => return 0u, - node::Content(x) => return node::char_len(x) - } -} - -/** - * The number of bytes in the rope - * - * # Performance note - * - * Constant time. - */ -pub fn byte_len(rope: Rope) -> uint { - match (rope) { - node::Empty => return 0u, - node::Content(x) => return node::byte_len(x) - } -} - -/** - * The character at position `pos` - * - * # Arguments - * - * * pos - A position in the rope - * - * # Safety notes - * - * The function will fail if `pos` is not a valid position in the rope. - * - * # Performance note - * - * This function executes in a time proportional to the height of the - * rope + the (bounded) length of the largest leaf. - */ -pub fn char_at(rope: Rope, pos: uint) -> char { - match (rope) { - node::Empty => fail!(), - node::Content(x) => return node::char_at(x, pos) - } -} - - -/* - Section: Implementation -*/ -pub mod node { - - use rope::node; - - use std::cast; - use std::uint; - use std::vec; - - /// Implementation of type `rope` - pub enum Root { - /// An empty rope - Empty, - /// A non-empty rope - Content(@Node), - } - - /** - * A text component in a rope. - * - * This is actually a slice in a rope, so as to ensure maximal sharing. - * - * # Fields - * - * * byte_offset = The number of bytes skipped in `content` - * * byte_len - The number of bytes of `content` to use - * * char_len - The number of chars in the leaf. - * * content - Contents of the leaf. - * - * Note that we can have `char_len < content.char_len()`, if - * this leaf is only a subset of the string. Also note that the - * string can be shared between several ropes, e.g. for indexing - * purposes. - */ - pub struct Leaf { - byte_offset: uint, - byte_len: uint, - char_len: uint, - content: @~str, - } - - /** - * A node obtained from the concatenation of two other nodes - * - * # Fields - * - * * left - The node containing the beginning of the text. - * * right - The node containing the end of the text. - * * char_len - The number of chars contained in all leaves of this node. - * * byte_len - The number of bytes in the subrope. - * - * Used to pre-allocate the correct amount of storage for - * serialization. - * - * * height - Height of the subrope. - * - * Used for rebalancing and to allocate stacks for traversals. - */ - pub struct Concat { - //FIXME (#2744): Perhaps a `vec` instead of `left`/`right` - left: @Node, - right: @Node, - char_len: uint, - byte_len: uint, - height: uint, - } - - pub enum Node { - /// A leaf consisting in a `str` - Leaf(Leaf), - /// The concatenation of two ropes - Concat(Concat), - } - - /** - * The maximal number of chars that _should_ be permitted in a single node - * - * This is not a strict value - */ - pub static hint_max_leaf_char_len: uint = 256u; - - /** - * The maximal height that _should_ be permitted in a tree. - * - * This is not a strict value - */ - pub static hint_max_node_height: uint = 16u; - - /** - * Adopt a string as a node. - * - * If the string is longer than `max_leaf_char_len`, it is - * logically split between as many leaves as necessary. Regardless, - * the string itself is not copied. - * - * Performance note: The complexity of this function is linear in - * the length of `str`. - */ - pub fn of_str(str: @~str) -> @Node { - return of_substr(str, 0u, str.len()); - } - - /** - * Adopt a slice of a string as a node. - * - * If the slice is longer than `max_leaf_char_len`, it is logically split - * between as many leaves as necessary. Regardless, the string itself - * is not copied - * - * # Arguments - * - * * byte_start - The byte offset where the slice of `str` starts. - * * byte_len - The number of bytes from `str` to use. - * - * # Safety note - * - * Behavior is undefined if `byte_start` or `byte_len` do not represent - * valid positions in `str` - */ - pub fn of_substr(str: @~str, byte_start: uint, byte_len: uint) -> @Node { - return of_substr_unsafer(str, byte_start, byte_len, - str.slice(byte_start, byte_start + byte_len).char_len()); - } - - /** - * Adopt a slice of a string as a node. - * - * If the slice is longer than `max_leaf_char_len`, it is logically split - * between as many leaves as necessary. Regardless, the string itself - * is not copied - * - * # Arguments - * - * * byte_start - The byte offset where the slice of `str` starts. - * * byte_len - The number of bytes from `str` to use. - * * char_len - The number of chars in `str` in the interval - * [byte_start, byte_start+byte_len) - * - * # Safety notes - * - * * Behavior is undefined if `byte_start` or `byte_len` do not represent - * valid positions in `str` - * * Behavior is undefined if `char_len` does not accurately represent the - * number of chars between byte_start and byte_start+byte_len - */ - pub fn of_substr_unsafer(str: @~str, byte_start: uint, byte_len: uint, - char_len: uint) -> @Node { - assert!((byte_start + byte_len <= str.len())); - let candidate = @Leaf(Leaf { - byte_offset: byte_start, - byte_len: byte_len, - char_len: char_len, - content: str, - }); - if char_len <= hint_max_leaf_char_len { - return candidate; - } else { - //Firstly, split `str` in slices of hint_max_leaf_char_len - let mut leaves = uint::div_ceil(char_len, hint_max_leaf_char_len); - //Number of leaves - let mut nodes = vec::from_elem(leaves, candidate); - - let mut i = 0u; - let mut offset = byte_start; - let first_leaf_char_len = - if char_len%hint_max_leaf_char_len == 0u { - hint_max_leaf_char_len - } else { - char_len%hint_max_leaf_char_len - }; - while i < leaves { - let chunk_char_len: uint = - if i == 0u { first_leaf_char_len } - else { hint_max_leaf_char_len }; - let chunk_byte_len = - str.slice_from(offset).slice_chars(0, chunk_char_len).len(); - nodes[i] = @Leaf(Leaf { - byte_offset: offset, - byte_len: chunk_byte_len, - char_len: chunk_char_len, - content: str, - }); - - offset += chunk_byte_len; - i += 1u; - } - - //Then, build a tree from these slices by collapsing them - while leaves > 1u { - i = 0u; - while i < leaves - 1u {//Concat nodes 0 with 1, 2 with 3 etc. - nodes[i/2u] = concat2(nodes[i], nodes[i + 1u]); - i += 2u; - } - if i == leaves - 1u { - //And don't forget the last node if it is in even position - nodes[i/2u] = nodes[i]; - } - leaves = uint::div_ceil(leaves, 2u); - } - return nodes[0u]; - } - } - - pub fn byte_len(node: @Node) -> uint { - //FIXME (#2744): Could we do this without the pattern-matching? - match (*node) { - Leaf(y) => y.byte_len, - Concat(ref y) => y.byte_len - } - } - - pub fn char_len(node: @Node) -> uint { - match (*node) { - Leaf(y) => y.char_len, - Concat(ref y) => y.char_len - } - } - - /** - * Concatenate a forest of nodes into one tree. - * - * # Arguments - * - * * forest - The forest. This vector is progressively rewritten during - * execution and should be discarded as meaningless afterwards. - */ - pub fn tree_from_forest_destructive(forest: &mut [@Node]) -> @Node { - let mut i; - let mut len = forest.len(); - while len > 1u { - i = 0u; - while i < len - 1u {//Concat nodes 0 with 1, 2 with 3 etc. - let mut left = forest[i]; - let mut right = forest[i+1u]; - let left_len = char_len(left); - let right_len= char_len(right); - let mut left_height= height(left); - let mut right_height=height(right); - if left_len + right_len > hint_max_leaf_char_len { - if left_len <= hint_max_leaf_char_len { - left = flatten(left); - left_height = height(left); - } - if right_len <= hint_max_leaf_char_len { - right = flatten(right); - right_height = height(right); - } - } - if left_height >= hint_max_node_height { - left = of_substr_unsafer(@serialize_node(left), - 0u,byte_len(left), - left_len); - } - if right_height >= hint_max_node_height { - right = of_substr_unsafer(@serialize_node(right), - 0u,byte_len(right), - right_len); - } - forest[i/2u] = concat2(left, right); - i += 2u; - } - if i == len - 1u { - //And don't forget the last node if it is in even position - forest[i/2u] = forest[i]; - } - len = uint::div_ceil(len, 2u); - } - return forest[0]; - } - - pub fn serialize_node(node: @Node) -> ~str { - unsafe { - let mut buf = vec::from_elem(byte_len(node), 0); - let mut offset = 0u;//Current position in the buffer - let mut it = leaf_iterator::start(node); - loop { - match leaf_iterator::next(&mut it) { - None => break, - Some(x) => { - //FIXME (#2744): Replace with memcpy or something similar - let local_buf: ~[u8] = cast::transmute(copy *x.content); - let mut i = x.byte_offset; - while i < x.byte_len { - buf[offset] = local_buf[i]; - offset += 1u; - i += 1u; - } - cast::forget(local_buf); - } - } - } - return cast::transmute(buf); - } - } - - /** - * Replace a subtree by a single leaf with the same contents. - * - * * Performance note - * - * This function executes in linear time. - */ - pub fn flatten(node: @Node) -> @Node { - match (*node) { - Leaf(_) => node, - Concat(ref x) => { - @Leaf(Leaf { - byte_offset: 0u, - byte_len: x.byte_len, - char_len: x.char_len, - content: @serialize_node(node), - }) - } - } - } - - /** - * Balance a node. - * - * # Algorithm - * - * * if the node height is smaller than `hint_max_node_height`, do nothing - * * otherwise, gather all leaves as a forest, rebuild a balanced node, - * concatenating small leaves along the way - * - * # Return value - * - * * `None` if no transformation happened - * * `Some(x)` otherwise, in which case `x` has the same contents - * as `node` bot lower height and/or fragmentation. - */ - pub fn bal(node: @Node) -> Option<@Node> { - if height(node) < hint_max_node_height { return None; } - //1. Gather all leaves as a forest - let mut forest = ~[]; - let mut it = leaf_iterator::start(node); - loop { - match leaf_iterator::next(&mut it) { - None => break, - Some(x) => forest.push(@Leaf(x)) - } - } - //2. Rebuild tree from forest - let root = @*tree_from_forest_destructive(forest); - return Some(root); - - } - - /** - * Compute the subnode of a node. - * - * # Arguments - * - * * node - A node - * * byte_offset - A byte offset in `node` - * * byte_len - The number of bytes to return - * - * # Performance notes - * - * * this function performs no copying; - * * this function executes in a time proportional to the height of `node` - * - * # Safety notes - * - * This function fails if `byte_offset` or `byte_len` do not represent - * valid positions in `node`. - */ - pub fn sub_bytes(node: @Node, byte_offset: uint, - byte_len: uint) -> @Node { - let mut node = node; - let mut byte_offset = byte_offset; - loop { - if byte_offset == 0u && byte_len == node::byte_len(node) { - return node; - } - match (*node) { - node::Leaf(x) => { - let char_len = - x.content.slice(byte_offset, byte_offset + byte_len).char_len(); - return @Leaf(Leaf { - byte_offset: byte_offset, - byte_len: byte_len, - char_len: char_len, - content: x.content, - }); - } - node::Concat(ref x) => { - let left_len: uint = node::byte_len(x.left); - if byte_offset <= left_len { - if byte_offset + byte_len <= left_len { - //Case 1: Everything fits in x.left, tail-call - node = x.left; - } else { - //Case 2: A (non-empty, possibly full) suffix - //of x.left and a (non-empty, possibly full) prefix - //of x.right - let left_result = - sub_bytes(x.left, byte_offset, left_len); - let right_result = - sub_bytes(x.right, 0u, left_len - byte_offset); - return concat2(left_result, right_result); - } - } else { - //Case 3: Everything fits in x.right - byte_offset -= left_len; - node = x.right; - } - } - } - }; - } - - /** - * Compute the subnode of a node. - * - * # Arguments - * - * * node - A node - * * char_offset - A char offset in `node` - * * char_len - The number of chars to return - * - * # Performance notes - * - * * this function performs no copying; - * * this function executes in a time proportional to the height of `node` - * - * # Safety notes - * - * This function fails if `char_offset` or `char_len` do not represent - * valid positions in `node`. - */ - pub fn sub_chars(node: @Node, char_offset: uint, - char_len: uint) -> @Node { - let mut node = node; - let mut char_offset = char_offset; - loop { - match (*node) { - node::Leaf(x) => { - if char_offset == 0u && char_len == x.char_len { - return node; - } - let byte_offset = - x.content.slice_chars(0, char_offset).len(); - let byte_len = - x.content.slice_from(byte_offset).slice_chars(0, char_len).len(); - return @Leaf(Leaf { - byte_offset: byte_offset, - byte_len: byte_len, - char_len: char_len, - content: x.content, - }); - } - node::Concat(ref x) => { - if char_offset == 0u && char_len == x.char_len {return node;} - let left_len : uint = node::char_len(x.left); - if char_offset <= left_len { - if char_offset + char_len <= left_len { - //Case 1: Everything fits in x.left, tail call - node = x.left; - } else { - //Case 2: A (non-empty, possibly full) suffix - //of x.left and a (non-empty, possibly full) prefix - //of x.right - let left_result = - sub_chars(x.left, char_offset, left_len); - let right_result = - sub_chars(x.right, 0u, left_len - char_offset); - return concat2(left_result, right_result); - } - } else { - //Case 3: Everything fits in x.right, tail call - node = x.right; - char_offset -= left_len; - } - } - } - }; - } - - pub fn concat2(left: @Node, right: @Node) -> @Node { - @Concat(Concat { - left: left, - right: right, - char_len: char_len(left) + char_len(right), - byte_len: byte_len(left) + byte_len(right), - height: uint::max(height(left), height(right)) + 1u, - }) - } - - pub fn height(node: @Node) -> uint { - match (*node) { - Leaf(_) => 0u, - Concat(ref x) => x.height, - } - } - - pub fn cmp(a: @Node, b: @Node) -> int { - let mut ita = char_iterator::start(a); - let mut itb = char_iterator::start(b); - let mut result = 0; - while result == 0 { - match (char_iterator::next(&mut ita), char_iterator::next(&mut itb)) - { - (None, None) => break, - (Some(chara), Some(charb)) => { - result = chara.cmp(&charb) as int; - } - (Some(_), _) => { - result = 1; - } - (_, Some(_)) => { - result = -1; - } - } - } - return result; - } - - 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(|c| it(c)) - }); - } - - /** - * Loop through a node, leaf by leaf - * - * # Arguments - * - * * rope - A node to traverse. - * * it - A block to execute with each consecutive leaf of the node. - * Return `true` to continue, `false` to stop - * - * # Arguments - * - * `true` If execution proceeded correctly, `false` if it was interrupted, - * that is if `it` returned `false` at any point. - */ - pub fn loop_leaves(node: @Node, it: &fn(Leaf) -> bool) -> bool{ - let mut current = node; - loop { - match (*current) { - Leaf(x) => return it(x), - Concat(ref x) => if loop_leaves(x.left, |l| it(l)) { //non tail call - current = x.right; //tail call - } else { - return false; - } - } - }; - } - - /** - * # Arguments - * - * * pos - A position in the rope - * - * # Return value - * - * The character at position `pos` - * - * # Safety notes - * - * The function will fail if `pos` is not a valid position in the rope. - * - * Performance note: This function executes in a time - * proportional to the height of the rope + the (bounded) - * length of the largest leaf. - */ - pub fn char_at(mut node: @Node, mut pos: uint) -> char { - loop { - match *node { - Leaf(x) => return x.content.char_at(pos), - Concat(Concat {left, right, _}) => { - let left_len = char_len(left); - node = if left_len > pos { left } - else { pos -= left_len; right }; - } - } - }; - } - - pub mod leaf_iterator { - - use rope::node::{Concat, Leaf, Node, height}; - - use std::vec; - - pub struct T { - stack: ~[@Node], - stackpos: int, - } - - pub fn empty() -> T { - let stack : ~[@Node] = ~[]; - T { stack: stack, stackpos: -1 } - } - - pub fn start(node: @Node) -> T { - let stack = vec::from_elem(height(node)+1u, node); - T { - stack: stack, - stackpos: 0, - } - } - - pub fn next(it: &mut T) -> Option { - if it.stackpos < 0 { return None; } - loop { - let current = it.stack[it.stackpos]; - it.stackpos -= 1; - match (*current) { - Concat(ref x) => { - it.stackpos += 1; - it.stack[it.stackpos] = x.right; - it.stackpos += 1; - it.stack[it.stackpos] = x.left; - } - Leaf(x) => return Some(x) - } - }; - } - } - - pub mod char_iterator { - - use rope::node::{Leaf, Node}; - use rope::node::leaf_iterator; - - pub struct T { - leaf_iterator: leaf_iterator::T, - leaf: Option, - leaf_byte_pos: uint, - } - - pub fn start(node: @Node) -> T { - T { - leaf_iterator: leaf_iterator::start(node), - leaf: None, - leaf_byte_pos: 0u, - } - } - - pub fn empty() -> T { - T { - leaf_iterator: leaf_iterator::empty(), - leaf: None, - leaf_byte_pos: 0u, - } - } - - pub fn next(it: &mut T) -> Option { - loop { - match get_current_or_next_leaf(it) { - None => return None, - Some(_) => { - let next_char = get_next_char_in_leaf(it); - match next_char { - None => loop, - Some(_) => return next_char - } - } - } - }; - } - - pub fn get_current_or_next_leaf(it: &mut T) -> Option { - match it.leaf { - Some(_) => return it.leaf, - None => { - let next = leaf_iterator::next(&mut it.leaf_iterator); - match next { - None => return None, - Some(_) => { - it.leaf = next; - it.leaf_byte_pos = 0u; - return next; - } - } - } - } - } - - pub fn get_next_char_in_leaf(it: &mut T) -> Option { - match copy it.leaf { - None => return None, - Some(aleaf) => { - if it.leaf_byte_pos >= aleaf.byte_len { - //We are actually past the end of the leaf - it.leaf = None; - return None - } else { - let range = - aleaf.content.char_range_at((*it).leaf_byte_pos + aleaf.byte_offset); - let ch = range.ch; - let next = range.next; - (*it).leaf_byte_pos = next - aleaf.byte_offset; - return Some(ch) - } - } - } - } - } -} - -#[cfg(test)] -mod tests { - - use rope::*; - - use std::uint; - use std::vec; - - //Utility function, used for sanity check - fn rope_to_string(r: Rope) -> ~str { - match (r) { - node::Empty => return ~"", - node::Content(x) => { - let mut str = ~""; - fn aux(str: &mut ~str, node: @node::Node) { - match (*node) { - node::Leaf(x) => { - str.push_str(x.content.slice(x.byte_offset, x.byte_offset + x.byte_len)); - } - node::Concat(ref x) => { - aux(str, x.left); - aux(str, x.right); - } - } - } - aux(&mut str, x); - return str - } - } - } - - - #[test] - fn trivial() { - assert_eq!(char_len(empty()), 0u); - assert_eq!(byte_len(empty()), 0u); - } - - #[test] - fn of_string1() { - let sample = @~"0123456789ABCDE"; - let r = of_str(sample); - - assert_eq!(char_len(r), sample.char_len()); - assert!(rope_to_string(r) == *sample); - } - - #[test] - fn of_string2() { - let buf = @ mut ~"1234567890"; - let mut i = 0; - while i < 10 { - let a = copy *buf; - let b = copy *buf; - *buf = a + b; - i+=1; - } - let sample = @copy *buf; - let r = of_str(sample); - assert_eq!(char_len(r), sample.char_len()); - assert!(rope_to_string(r) == *sample); - - let mut string_iter = 0u; - let string_len = sample.len(); - let mut rope_iter = iterator::char::start(r); - let mut equal = true; - while equal { - match (node::char_iterator::next(&mut rope_iter)) { - None => { - if string_iter < string_len { - equal = false; - } break; } - Some(c) => { - let range = sample.char_range_at(string_iter); - string_iter = range.next; - if range.ch != c { equal = false; break; } - } - } - } - - assert!(equal); - } - - #[test] - fn iter1() { - let buf = @ mut ~"1234567890"; - let mut i = 0; - while i < 10 { - let a = copy *buf; - let b = copy *buf; - *buf = a + b; - i+=1; - } - let sample = @copy *buf; - let r = of_str(sample); - - let mut len = 0u; - let mut it = iterator::char::start(r); - loop { - match (node::char_iterator::next(&mut it)) { - None => break, - Some(_) => len += 1u - } - } - - assert_eq!(len, sample.char_len()); - } - - #[test] - fn bal1() { - let init = @~"1234567890"; - let buf = @mut copy *init; - let mut i = 0; - while i < 8 { - let a = copy *buf; - let b = copy *buf; - *buf = a + b; - i+=1; - } - let sample = @copy *buf; - let r1 = of_str(sample); - let mut r2 = of_str(init); - i = 0; - while i < 8 { r2 = append_rope(r2, r2); i+= 1;} - - - assert!(eq(r1, r2)); - let r3 = bal(r2); - assert_eq!(char_len(r1), char_len(r3)); - - assert!(eq(r1, r3)); - } - - #[test] - #[ignore] - fn char_at1() { - //Generate a large rope - let mut r = of_str(@~"123456789"); - for uint::range(0u, 10u) |_i| { - r = append_rope(r, r); - } - - //Copy it in the slowest possible way - let mut r2 = empty(); - for uint::range(0u, char_len(r)) |i| { - r2 = append_char(r2, char_at(r, i)); - } - assert!(eq(r, r2)); - - let mut r3 = empty(); - for uint::range(0u, char_len(r)) |i| { - r3 = prepend_char(r3, char_at(r, char_len(r) - i - 1u)); - } - assert!(eq(r, r3)); - - //Additional sanity checks - let balr = bal(r); - let bal2 = bal(r2); - let bal3 = bal(r3); - assert!(eq(r, balr)); - assert!(eq(r, bal2)); - assert!(eq(r, bal3)); - assert!(eq(r2, r3)); - assert!(eq(bal2, bal3)); - } - - #[test] - fn concat1() { - //Generate a reasonable rope - let chunk = of_str(@~"123456789"); - let mut r = empty(); - for uint::range(0u, 10u) |_i| { - r = append_rope(r, chunk); - } - - //Same rope, obtained with rope::concat - let r2 = concat(vec::from_elem(10u, chunk)); - - assert!(eq(r, r2)); - } -} diff --git a/src/libextra/serialize.rs b/src/libextra/serialize.rs index 66b178f49f7f..b1383948bf72 100644 --- a/src/libextra/serialize.rs +++ b/src/libextra/serialize.rs @@ -682,7 +682,7 @@ impl< > Encodable for Deque { 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)); } } diff --git a/src/libextra/stats.rs b/src/libextra/stats.rs index 8351e4db6b8c..0271b393f611 100644 --- a/src/libextra/stats.rs +++ b/src/libextra/stats.rs @@ -8,32 +8,135 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(missing_doc)]; - - -use std::f64; -use std::cmp; -use std::num; -use std::vec; use sort; +use std::cmp; +use std::io; +use std::num; +use std::f64; +use std::vec; // NB: this can probably be rewritten in terms of num::Num // to be less f64-specific. +/// Trait that provides simple descriptive statistics on a univariate set of numeric samples. pub trait Stats { + + /// Sum of the samples. fn sum(self) -> f64; + + /// Minimum value of the samples. fn min(self) -> f64; + + /// Maximum value of the samples. fn max(self) -> f64; + + /// Arithmetic mean (average) of the samples: sum divided by sample-count. + /// + /// See: https://en.wikipedia.org/wiki/Arithmetic_mean fn mean(self) -> f64; + + /// Median of the samples: value separating the lower half of the samples from the higher half. + /// Equal to `self.percentile(50.0)`. + /// + /// See: https://en.wikipedia.org/wiki/Median fn median(self) -> f64; + + /// Variance of the samples: bias-corrected mean of the squares of the differences of each + /// sample from the sample mean. Note that this calculates the _sample variance_ rather than the + /// population variance, which is assumed to be unknown. It therefore corrects the `(n-1)/n` + /// bias that would appear if we calculated a population variance, by dividing by `(n-1)` rather + /// than `n`. + /// + /// See: https://en.wikipedia.org/wiki/Variance fn var(self) -> f64; + + /// Standard deviation: the square root of the sample variance. + /// + /// Note: this is not a robust statistic for non-normal distributions. Prefer the + /// `median_abs_dev` for unknown distributions. + /// + /// See: https://en.wikipedia.org/wiki/Standard_deviation fn std_dev(self) -> f64; + + /// Standard deviation as a percent of the mean value. See `std_dev` and `mean`. + /// + /// Note: this is not a robust statistic for non-normal distributions. Prefer the + /// `median_abs_dev_pct` for unknown distributions. fn std_dev_pct(self) -> f64; + + /// Scaled median of the absolute deviations of each sample from the sample median. This is a + /// robust (distribution-agnostic) estimator of sample variability. Use this in preference to + /// `std_dev` if you cannot assume your sample is normally distributed. Note that this is scaled + /// by the constant `1.4826` to allow its use as a consistent estimator for the standard + /// deviation. + /// + /// See: http://en.wikipedia.org/wiki/Median_absolute_deviation fn median_abs_dev(self) -> f64; + + /// Median absolute deviation as a percent of the median. See `median_abs_dev` and `median`. fn median_abs_dev_pct(self) -> f64; + + /// Percentile: the value below which `pct` percent of the values in `self` fall. For example, + /// percentile(95.0) will return the value `v` such that that 95% of the samples `s` in `self` + /// satisfy `s <= v`. + /// + /// Calculated by linear interpolation between closest ranks. + /// + /// See: http://en.wikipedia.org/wiki/Percentile + fn percentile(self, pct: f64) -> f64; + + /// Quartiles of the sample: three values that divide the sample into four equal groups, each + /// with 1/4 of the data. The middle value is the median. See `median` and `percentile`. This + /// function may calculate the 3 quartiles more efficiently than 3 calls to `percentile`, but + /// is otherwise equivalent. + /// + /// See also: https://en.wikipedia.org/wiki/Quartile + fn quartiles(self) -> (f64,f64,f64); + + /// Inter-quartile range: the difference between the 25th percentile (1st quartile) and the 75th + /// percentile (3rd quartile). See `quartiles`. + /// + /// See also: https://en.wikipedia.org/wiki/Interquartile_range + fn iqr(self) -> f64; +} + +/// Extracted collection of all the summary statistics of a sample set. +struct Summary { + sum: f64, + min: f64, + max: f64, + mean: f64, + median: f64, + var: f64, + std_dev: f64, + std_dev_pct: f64, + median_abs_dev: f64, + median_abs_dev_pct: f64, + quartiles: (f64,f64,f64), + iqr: f64, +} + +impl Summary { + fn new(samples: &[f64]) -> Summary { + Summary { + sum: samples.sum(), + min: samples.min(), + max: samples.max(), + mean: samples.mean(), + median: samples.median(), + var: samples.var(), + std_dev: samples.std_dev(), + std_dev_pct: samples.std_dev_pct(), + median_abs_dev: samples.median_abs_dev(), + median_abs_dev_pct: samples.median_abs_dev_pct(), + quartiles: samples.quartiles(), + iqr: samples.iqr() + } + } } impl<'self> Stats for &'self [f64] { + fn sum(self) -> f64 { self.iter().fold(0.0, |p,q| p + *q) } @@ -54,19 +157,11 @@ impl<'self> Stats for &'self [f64] { } fn median(self) -> f64 { - assert!(self.len() != 0); - let mut tmp = vec::to_owned(self); - sort::tim_sort(tmp); - if tmp.len() & 1 == 0 { - let m = tmp.len() / 2; - (tmp[m] + tmp[m-1]) / 2.0 - } else { - tmp[tmp.len() / 2] - } + self.percentile(50.0) } fn var(self) -> f64 { - if self.len() == 0 { + if self.len() < 2 { 0.0 } else { let mean = self.mean(); @@ -75,7 +170,10 @@ impl<'self> Stats for &'self [f64] { let x = *s - mean; v += x*x; } - v/(self.len() as f64) + // NB: this is _supposed to be_ len-1, not len. If you + // change it back to len, you will be calculating a + // population variance, not a sample variance. + v/((self.len()-1) as f64) } } @@ -89,11 +187,725 @@ impl<'self> Stats for &'self [f64] { fn median_abs_dev(self) -> f64 { let med = self.median(); - let abs_devs = self.map(|v| num::abs(med - *v)); - abs_devs.median() + let abs_devs = self.map(|&v| num::abs(med - v)); + // This constant is derived by smarter statistics brains than me, but it is + // consistent with how R and other packages treat the MAD. + abs_devs.median() * 1.4826 } fn median_abs_dev_pct(self) -> f64 { (self.median_abs_dev() / self.median()) * 100.0 } + + fn percentile(self, pct: f64) -> f64 { + let mut tmp = vec::to_owned(self); + sort::tim_sort(tmp); + percentile_of_sorted(tmp, pct) + } + + fn quartiles(self) -> (f64,f64,f64) { + let mut tmp = vec::to_owned(self); + sort::tim_sort(tmp); + let a = percentile_of_sorted(tmp, 25.0); + let b = percentile_of_sorted(tmp, 50.0); + let c = percentile_of_sorted(tmp, 75.0); + (a,b,c) + } + + fn iqr(self) -> f64 { + let (a,_,c) = self.quartiles(); + c - a + } +} + + +// Helper function: extract a value representing the `pct` percentile of a sorted sample-set, using +// linear interpolation. If samples are not sorted, return nonsensical value. +priv fn percentile_of_sorted(sorted_samples: &[f64], + pct: f64) -> f64 { + assert!(sorted_samples.len() != 0); + if sorted_samples.len() == 1 { + return sorted_samples[0]; + } + assert!(0.0 <= pct); + assert!(pct <= 100.0); + if pct == 100.0 { + return sorted_samples[sorted_samples.len() - 1]; + } + let rank = (pct / 100.0) * ((sorted_samples.len() - 1) as f64); + let lrank = rank.floor(); + let d = rank - lrank; + let n = lrank as uint; + let lo = sorted_samples[n]; + let hi = sorted_samples[n+1]; + lo + (hi - lo) * d +} + + +/// Winsorize a set of samples, replacing values above the `100-pct` percentile and below the `pct` +/// percentile with those percentiles themselves. This is a way of minimizing the effect of +/// outliers, at the cost of biasing the sample. It differs from trimming in that it does not +/// change the number of samples, just changes the values of those that are outliers. +/// +/// See: http://en.wikipedia.org/wiki/Winsorising +pub fn winsorize(samples: &mut [f64], pct: f64) { + let mut tmp = vec::to_owned(samples); + sort::tim_sort(tmp); + let lo = percentile_of_sorted(tmp, pct); + let hi = percentile_of_sorted(tmp, 100.0-pct); + for samples.mut_iter().advance |samp| { + if *samp > hi { + *samp = hi + } else if *samp < lo { + *samp = lo + } + } +} + +/// Render writes the min, max and quartiles of the provided `Summary` to the provided `Writer`. +pub fn write_5_number_summary(w: @io::Writer, s: &Summary) { + let (q1,q2,q3) = s.quartiles; + w.write_str(fmt!("(min=%f, q1=%f, med=%f, q3=%f, max=%f)", + s.min as float, + q1 as float, + q2 as float, + q3 as float, + s.max as float)); +} + +/// Render a boxplot to the provided writer. The boxplot shows the min, max and quartiles of the +/// provided `Summary` (thus includes the mean) and is scaled to display within the range of the +/// nearest multiple-of-a-power-of-ten above and below the min and max of possible values, and +/// target `width_hint` characters of display (though it will be wider if necessary). +/// +/// As an example, the summary with 5-number-summary `(min=15, q1=17, med=20, q3=24, max=31)` might +/// display as: +/// +/// ~~~~ +/// 10 | [--****#******----------] | 40 +/// ~~~~ + +pub fn write_boxplot(w: @io::Writer, s: &Summary, width_hint: uint) { + + let (q1,q2,q3) = s.quartiles; + + let lomag = (10.0_f64).pow(&s.min.log10().floor()); + let himag = (10.0_f64).pow(&(s.max.log10().floor())); + let lo = (s.min / lomag).floor() * lomag; + let hi = (s.max / himag).ceil() * himag; + + let range = hi - lo; + + let lostr = lo.to_str(); + let histr = hi.to_str(); + + let overhead_width = lostr.len() + histr.len() + 4; + let range_width = width_hint - overhead_width;; + let char_step = range / (range_width as f64); + + w.write_str(lostr); + w.write_char(' '); + w.write_char('|'); + + let mut c = 0; + let mut v = lo; + + while c < range_width && v < s.min { + w.write_char(' '); + v += char_step; + c += 1; + } + w.write_char('['); + c += 1; + while c < range_width && v < q1 { + w.write_char('-'); + v += char_step; + c += 1; + } + while c < range_width && v < q2 { + w.write_char('*'); + v += char_step; + c += 1; + } + w.write_char('#'); + c += 1; + while c < range_width && v < q3 { + w.write_char('*'); + v += char_step; + c += 1; + } + while c < range_width && v < s.max { + w.write_char('-'); + v += char_step; + c += 1; + } + w.write_char(']'); + while c < range_width { + w.write_char(' '); + v += char_step; + c += 1; + } + + w.write_char('|'); + w.write_char(' '); + w.write_str(histr); +} + +// Test vectors generated from R, using the script src/etc/stat-test-vectors.r. + +#[cfg(test)] +mod tests { + + use stats::Stats; + use stats::Summary; + use stats::write_5_number_summary; + use stats::write_boxplot; + use std::io; + + fn check(samples: &[f64], summ: &Summary) { + + let summ2 = Summary::new(samples); + + let w = io::stdout(); + w.write_char('\n'); + write_5_number_summary(w, &summ2); + w.write_char('\n'); + write_boxplot(w, &summ2, 50); + w.write_char('\n'); + + assert_eq!(summ.sum, summ2.sum); + assert_eq!(summ.min, summ2.min); + assert_eq!(summ.max, summ2.max); + assert_eq!(summ.mean, summ2.mean); + assert_eq!(summ.median, summ2.median); + + // We needed a few more digits to get exact equality on these + // but they're within float epsilon, which is 1.0e-6. + assert_approx_eq!(summ.var, summ2.var); + assert_approx_eq!(summ.std_dev, summ2.std_dev); + assert_approx_eq!(summ.std_dev_pct, summ2.std_dev_pct); + assert_approx_eq!(summ.median_abs_dev, summ2.median_abs_dev); + assert_approx_eq!(summ.median_abs_dev_pct, summ2.median_abs_dev_pct); + + assert_eq!(summ.quartiles, summ2.quartiles); + assert_eq!(summ.iqr, summ2.iqr); + } + + #[test] + fn test_norm2() { + let val = &[ + 958.0000000000, + 924.0000000000, + ]; + let summ = &Summary { + sum: 1882.0000000000, + min: 924.0000000000, + max: 958.0000000000, + mean: 941.0000000000, + median: 941.0000000000, + var: 578.0000000000, + std_dev: 24.0416305603, + std_dev_pct: 2.5549022912, + median_abs_dev: 25.2042000000, + median_abs_dev_pct: 2.6784484591, + quartiles: (932.5000000000,941.0000000000,949.5000000000), + iqr: 17.0000000000, + }; + check(val, summ); + } + #[test] + fn test_norm10narrow() { + let val = &[ + 966.0000000000, + 985.0000000000, + 1110.0000000000, + 848.0000000000, + 821.0000000000, + 975.0000000000, + 962.0000000000, + 1157.0000000000, + 1217.0000000000, + 955.0000000000, + ]; + let summ = &Summary { + sum: 9996.0000000000, + min: 821.0000000000, + max: 1217.0000000000, + mean: 999.6000000000, + median: 970.5000000000, + var: 16050.7111111111, + std_dev: 126.6914010938, + std_dev_pct: 12.6742097933, + median_abs_dev: 102.2994000000, + median_abs_dev_pct: 10.5408964451, + quartiles: (956.7500000000,970.5000000000,1078.7500000000), + iqr: 122.0000000000, + }; + check(val, summ); + } + #[test] + fn test_norm10medium() { + let val = &[ + 954.0000000000, + 1064.0000000000, + 855.0000000000, + 1000.0000000000, + 743.0000000000, + 1084.0000000000, + 704.0000000000, + 1023.0000000000, + 357.0000000000, + 869.0000000000, + ]; + let summ = &Summary { + sum: 8653.0000000000, + min: 357.0000000000, + max: 1084.0000000000, + mean: 865.3000000000, + median: 911.5000000000, + var: 48628.4555555556, + std_dev: 220.5186059170, + std_dev_pct: 25.4846418487, + median_abs_dev: 195.7032000000, + median_abs_dev_pct: 21.4704552935, + quartiles: (771.0000000000,911.5000000000,1017.2500000000), + iqr: 246.2500000000, + }; + check(val, summ); + } + #[test] + fn test_norm10wide() { + let val = &[ + 505.0000000000, + 497.0000000000, + 1591.0000000000, + 887.0000000000, + 1026.0000000000, + 136.0000000000, + 1580.0000000000, + 940.0000000000, + 754.0000000000, + 1433.0000000000, + ]; + let summ = &Summary { + sum: 9349.0000000000, + min: 136.0000000000, + max: 1591.0000000000, + mean: 934.9000000000, + median: 913.5000000000, + var: 239208.9888888889, + std_dev: 489.0899599142, + std_dev_pct: 52.3146817750, + median_abs_dev: 611.5725000000, + median_abs_dev_pct: 66.9482758621, + quartiles: (567.2500000000,913.5000000000,1331.2500000000), + iqr: 764.0000000000, + }; + check(val, summ); + } + #[test] + fn test_norm25verynarrow() { + let val = &[ + 991.0000000000, + 1018.0000000000, + 998.0000000000, + 1013.0000000000, + 974.0000000000, + 1007.0000000000, + 1014.0000000000, + 999.0000000000, + 1011.0000000000, + 978.0000000000, + 985.0000000000, + 999.0000000000, + 983.0000000000, + 982.0000000000, + 1015.0000000000, + 1002.0000000000, + 977.0000000000, + 948.0000000000, + 1040.0000000000, + 974.0000000000, + 996.0000000000, + 989.0000000000, + 1015.0000000000, + 994.0000000000, + 1024.0000000000, + ]; + let summ = &Summary { + sum: 24926.0000000000, + min: 948.0000000000, + max: 1040.0000000000, + mean: 997.0400000000, + median: 998.0000000000, + var: 393.2066666667, + std_dev: 19.8294393937, + std_dev_pct: 1.9888308788, + median_abs_dev: 22.2390000000, + median_abs_dev_pct: 2.2283567134, + quartiles: (983.0000000000,998.0000000000,1013.0000000000), + iqr: 30.0000000000, + }; + check(val, summ); + } + #[test] + fn test_exp10a() { + let val = &[ + 23.0000000000, + 11.0000000000, + 2.0000000000, + 57.0000000000, + 4.0000000000, + 12.0000000000, + 5.0000000000, + 29.0000000000, + 3.0000000000, + 21.0000000000, + ]; + let summ = &Summary { + sum: 167.0000000000, + min: 2.0000000000, + max: 57.0000000000, + mean: 16.7000000000, + median: 11.5000000000, + var: 287.7888888889, + std_dev: 16.9643416875, + std_dev_pct: 101.5828843560, + median_abs_dev: 13.3434000000, + median_abs_dev_pct: 116.0295652174, + quartiles: (4.2500000000,11.5000000000,22.5000000000), + iqr: 18.2500000000, + }; + check(val, summ); + } + #[test] + fn test_exp10b() { + let val = &[ + 24.0000000000, + 17.0000000000, + 6.0000000000, + 38.0000000000, + 25.0000000000, + 7.0000000000, + 51.0000000000, + 2.0000000000, + 61.0000000000, + 32.0000000000, + ]; + let summ = &Summary { + sum: 263.0000000000, + min: 2.0000000000, + max: 61.0000000000, + mean: 26.3000000000, + median: 24.5000000000, + var: 383.5666666667, + std_dev: 19.5848580967, + std_dev_pct: 74.4671410520, + median_abs_dev: 22.9803000000, + median_abs_dev_pct: 93.7971428571, + quartiles: (9.5000000000,24.5000000000,36.5000000000), + iqr: 27.0000000000, + }; + check(val, summ); + } + #[test] + fn test_exp10c() { + let val = &[ + 71.0000000000, + 2.0000000000, + 32.0000000000, + 1.0000000000, + 6.0000000000, + 28.0000000000, + 13.0000000000, + 37.0000000000, + 16.0000000000, + 36.0000000000, + ]; + let summ = &Summary { + sum: 242.0000000000, + min: 1.0000000000, + max: 71.0000000000, + mean: 24.2000000000, + median: 22.0000000000, + var: 458.1777777778, + std_dev: 21.4050876611, + std_dev_pct: 88.4507754589, + median_abs_dev: 21.4977000000, + median_abs_dev_pct: 97.7168181818, + quartiles: (7.7500000000,22.0000000000,35.0000000000), + iqr: 27.2500000000, + }; + check(val, summ); + } + #[test] + fn test_exp25() { + let val = &[ + 3.0000000000, + 24.0000000000, + 1.0000000000, + 19.0000000000, + 7.0000000000, + 5.0000000000, + 30.0000000000, + 39.0000000000, + 31.0000000000, + 13.0000000000, + 25.0000000000, + 48.0000000000, + 1.0000000000, + 6.0000000000, + 42.0000000000, + 63.0000000000, + 2.0000000000, + 12.0000000000, + 108.0000000000, + 26.0000000000, + 1.0000000000, + 7.0000000000, + 44.0000000000, + 25.0000000000, + 11.0000000000, + ]; + let summ = &Summary { + sum: 593.0000000000, + min: 1.0000000000, + max: 108.0000000000, + mean: 23.7200000000, + median: 19.0000000000, + var: 601.0433333333, + std_dev: 24.5161851301, + std_dev_pct: 103.3565983562, + median_abs_dev: 19.2738000000, + median_abs_dev_pct: 101.4410526316, + quartiles: (6.0000000000,19.0000000000,31.0000000000), + iqr: 25.0000000000, + }; + check(val, summ); + } + #[test] + fn test_binom25() { + let val = &[ + 18.0000000000, + 17.0000000000, + 27.0000000000, + 15.0000000000, + 21.0000000000, + 25.0000000000, + 17.0000000000, + 24.0000000000, + 25.0000000000, + 24.0000000000, + 26.0000000000, + 26.0000000000, + 23.0000000000, + 15.0000000000, + 23.0000000000, + 17.0000000000, + 18.0000000000, + 18.0000000000, + 21.0000000000, + 16.0000000000, + 15.0000000000, + 31.0000000000, + 20.0000000000, + 17.0000000000, + 15.0000000000, + ]; + let summ = &Summary { + sum: 514.0000000000, + min: 15.0000000000, + max: 31.0000000000, + mean: 20.5600000000, + median: 20.0000000000, + var: 20.8400000000, + std_dev: 4.5650848842, + std_dev_pct: 22.2037202539, + median_abs_dev: 5.9304000000, + median_abs_dev_pct: 29.6520000000, + quartiles: (17.0000000000,20.0000000000,24.0000000000), + iqr: 7.0000000000, + }; + check(val, summ); + } + #[test] + fn test_pois25lambda30() { + let val = &[ + 27.0000000000, + 33.0000000000, + 34.0000000000, + 34.0000000000, + 24.0000000000, + 39.0000000000, + 28.0000000000, + 27.0000000000, + 31.0000000000, + 28.0000000000, + 38.0000000000, + 21.0000000000, + 33.0000000000, + 36.0000000000, + 29.0000000000, + 37.0000000000, + 32.0000000000, + 34.0000000000, + 31.0000000000, + 39.0000000000, + 25.0000000000, + 31.0000000000, + 32.0000000000, + 40.0000000000, + 24.0000000000, + ]; + let summ = &Summary { + sum: 787.0000000000, + min: 21.0000000000, + max: 40.0000000000, + mean: 31.4800000000, + median: 32.0000000000, + var: 26.5933333333, + std_dev: 5.1568724372, + std_dev_pct: 16.3814245145, + median_abs_dev: 5.9304000000, + median_abs_dev_pct: 18.5325000000, + quartiles: (28.0000000000,32.0000000000,34.0000000000), + iqr: 6.0000000000, + }; + check(val, summ); + } + #[test] + fn test_pois25lambda40() { + let val = &[ + 42.0000000000, + 50.0000000000, + 42.0000000000, + 46.0000000000, + 34.0000000000, + 45.0000000000, + 34.0000000000, + 49.0000000000, + 39.0000000000, + 28.0000000000, + 40.0000000000, + 35.0000000000, + 37.0000000000, + 39.0000000000, + 46.0000000000, + 44.0000000000, + 32.0000000000, + 45.0000000000, + 42.0000000000, + 37.0000000000, + 48.0000000000, + 42.0000000000, + 33.0000000000, + 42.0000000000, + 48.0000000000, + ]; + let summ = &Summary { + sum: 1019.0000000000, + min: 28.0000000000, + max: 50.0000000000, + mean: 40.7600000000, + median: 42.0000000000, + var: 34.4400000000, + std_dev: 5.8685603004, + std_dev_pct: 14.3978417577, + median_abs_dev: 5.9304000000, + median_abs_dev_pct: 14.1200000000, + quartiles: (37.0000000000,42.0000000000,45.0000000000), + iqr: 8.0000000000, + }; + check(val, summ); + } + #[test] + fn test_pois25lambda50() { + let val = &[ + 45.0000000000, + 43.0000000000, + 44.0000000000, + 61.0000000000, + 51.0000000000, + 53.0000000000, + 59.0000000000, + 52.0000000000, + 49.0000000000, + 51.0000000000, + 51.0000000000, + 50.0000000000, + 49.0000000000, + 56.0000000000, + 42.0000000000, + 52.0000000000, + 51.0000000000, + 43.0000000000, + 48.0000000000, + 48.0000000000, + 50.0000000000, + 42.0000000000, + 43.0000000000, + 42.0000000000, + 60.0000000000, + ]; + let summ = &Summary { + sum: 1235.0000000000, + min: 42.0000000000, + max: 61.0000000000, + mean: 49.4000000000, + median: 50.0000000000, + var: 31.6666666667, + std_dev: 5.6273143387, + std_dev_pct: 11.3913245723, + median_abs_dev: 4.4478000000, + median_abs_dev_pct: 8.8956000000, + quartiles: (44.0000000000,50.0000000000,52.0000000000), + iqr: 8.0000000000, + }; + check(val, summ); + } + #[test] + fn test_unif25() { + let val = &[ + 99.0000000000, + 55.0000000000, + 92.0000000000, + 79.0000000000, + 14.0000000000, + 2.0000000000, + 33.0000000000, + 49.0000000000, + 3.0000000000, + 32.0000000000, + 84.0000000000, + 59.0000000000, + 22.0000000000, + 86.0000000000, + 76.0000000000, + 31.0000000000, + 29.0000000000, + 11.0000000000, + 41.0000000000, + 53.0000000000, + 45.0000000000, + 44.0000000000, + 98.0000000000, + 98.0000000000, + 7.0000000000, + ]; + let summ = &Summary { + sum: 1242.0000000000, + min: 2.0000000000, + max: 99.0000000000, + mean: 49.6800000000, + median: 45.0000000000, + var: 1015.6433333333, + std_dev: 31.8691595957, + std_dev_pct: 64.1488719719, + median_abs_dev: 45.9606000000, + median_abs_dev_pct: 102.1346666667, + quartiles: (29.0000000000,45.0000000000,79.0000000000), + iqr: 50.0000000000, + }; + check(val, summ); + } } diff --git a/src/libextra/term.rs b/src/libextra/term.rs index e21e5c5fb585..556266227757 100644 --- a/src/libextra/term.rs +++ b/src/libextra/term.rs @@ -26,23 +26,23 @@ use std::io; 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 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; + 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"))] diff --git a/src/libextra/terminfo/parser/compiled.rs b/src/libextra/terminfo/parser/compiled.rs index 063d26d1424b..e56b3b6bcf4c 100644 --- a/src/libextra/terminfo/parser/compiled.rs +++ b/src/libextra/terminfo/parser/compiled.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[allow(non_uppercase_statics)]; + /// ncurses-compatible compiled terminfo format parsing (term(5)) @@ -292,7 +294,7 @@ pub fn parse(file: @Reader, longnames: bool) -> Result<~TermInfo, ~str> { // Find the offset of the NUL we want to go to let nulpos = string_table.slice(offset as uint, string_table_bytes as uint) - .iter().position_(|&b| b == 0); + .iter().position(|&b| b == 0); match nulpos { Some(len) => { string_map.insert(name.to_owned(), diff --git a/src/libextra/test.rs b/src/libextra/test.rs index f3051e083839..1c6e2a25c01b 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -323,19 +323,19 @@ 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, @@ -469,7 +469,7 @@ fn run_tests(opts: &TestOpts, } // All benchmarks run at the end, in serial. - do vec::consume(filtered_benchs) |_, b| { + for filtered_benchs.consume_iter().advance |b| { callback(TeWait(copy b.desc)); run_test(!opts.run_benchmarks, b, ch.clone()); let (test, result) = p.recv(); @@ -479,16 +479,16 @@ fn run_tests(opts: &TestOpts, // Windows tends to dislike being overloaded with threads. #[cfg(windows)] -static sched_overcommit : uint = 1; +static SCHED_OVERCOMMIT : uint = 1; #[cfg(unix)] -static sched_overcommit : uint = 4u; +static SCHED_OVERCOMMIT : uint = 4u; fn get_concurrency() -> uint { use std::rt; let threads = rt::util::default_sched_threads(); if threads == 1 { 1 } - else { threads * sched_overcommit } + else { threads * SCHED_OVERCOMMIT } } #[allow(non_implicitly_copyable_typarams)] @@ -514,7 +514,7 @@ pub fn filter_tests( } else { return option::None; } } - vec::filter_map(filtered, |x| filter_fn(x, filter_str)) + filtered.consume_iter().filter_map(|x| filter_fn(x, filter_str)).collect() }; // Maybe pull out the ignored test and unignore them @@ -532,7 +532,7 @@ pub fn filter_tests( None } }; - vec::filter_map(filtered, |x| filter(x)) + filtered.consume_iter().filter_map(|x| filter(x)).collect() }; // Sort the tests alphabetically @@ -711,9 +711,9 @@ impl BenchHarness { // Eliminate outliers let med = samples.median(); let mad = samples.median_abs_dev(); - let samples = do vec::filter(samples) |f| { + let samples = do samples.consume_iter().filter |f| { num::abs(*f - med) <= 3.0 * mad - }; + }.collect::<~[f64]>(); debug!("%u samples, median %f, MAD=%f, %u survived filter", n_samples, med as float, mad as float, diff --git a/src/libextra/time.rs b/src/libextra/time.rs index e1f42934b390..a64b23743287 100644 --- a/src/libextra/time.rs +++ b/src/libextra/time.rs @@ -868,20 +868,20 @@ mod tests { use std::str; fn test_get_time() { - static some_recent_date: i64 = 1325376000i64; // 2012-01-01T00:00:00Z - static some_future_date: i64 = 1577836800i64; // 2020-01-01T00:00:00Z + static SOME_RECENT_DATE: i64 = 1325376000i64; // 2012-01-01T00:00:00Z + static SOME_FUTURE_DATE: i64 = 1577836800i64; // 2020-01-01T00:00:00Z let tv1 = get_time(); debug!("tv1=%? sec + %? nsec", tv1.sec as uint, tv1.nsec as uint); - assert!(tv1.sec > some_recent_date); + assert!(tv1.sec > SOME_RECENT_DATE); assert!(tv1.nsec < 1000000000i32); let tv2 = get_time(); debug!("tv2=%? sec + %? nsec", tv2.sec as uint, tv2.nsec as uint); assert!(tv2.sec >= tv1.sec); - assert!(tv2.sec < some_future_date); + assert!(tv2.sec < SOME_FUTURE_DATE); assert!(tv2.nsec < 1000000000i32); if tv2.sec == tv1.sec { assert!(tv2.nsec >= tv1.nsec); diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 5e898f8e59d9..a5f7479d41a0 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -57,23 +57,25 @@ impl Eq for TreeMap { } // Lexicographical comparison -fn lt(a: &TreeMap, +fn lt(a: &TreeMap, b: &TreeMap) -> bool { let mut x = a.iter(); let mut y = b.iter(); let (a_len, b_len) = (a.len(), b.len()); for uint::min(a_len, b_len).times { - let (key_a,_) = x.next().unwrap(); - let (key_b,_) = y.next().unwrap(); + let (key_a, value_a) = x.next().unwrap(); + let (key_b, value_b) = y.next().unwrap(); if *key_a < *key_b { return true; } if *key_a > *key_b { return false; } - }; + if *value_a < *value_b { return true; } + if *value_a > *value_b { return false; } + } a_len < b_len } -impl Ord for TreeMap { +impl Ord for TreeMap { #[inline] fn lt(&self, other: &TreeMap) -> bool { lt(self, other) } #[inline] @@ -196,14 +198,15 @@ impl TreeMap { /// Get a lazy iterator over the key-value pairs in the map. /// Requires that it be frozen (immutable). pub fn iter<'a>(&'a self) -> TreeMapIterator<'a, K, V> { - TreeMapIterator{stack: ~[], node: &self.root} + TreeMapIterator{stack: ~[], node: &self.root, remaining: self.length} } } /// Lazy forward iterator over a map pub struct TreeMapIterator<'self, K, V> { priv stack: ~[&'self ~TreeNode], - priv node: &'self Option<~TreeNode> + priv node: &'self Option<~TreeNode>, + priv remaining: uint } impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapIterator<'self, K, V> { @@ -220,12 +223,18 @@ impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapIterator<'self, K, V None => { let res = self.stack.pop(); self.node = &res.right; + self.remaining -= 1; return Some((&res.key, &res.value)); } } } None } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + (self.remaining, Some(self.remaining)) + } } impl<'self, T> Iterator<&'self T> for TreeSetIterator<'self, T> { @@ -835,7 +844,7 @@ mod test_treemap { for 90.times { let k = rng.gen(); let v = rng.gen(); - if !ctrl.iter().any_(|x| x == &(k, v)) { + if !ctrl.iter().any(|x| x == &(k, v)) { assert!(map.insert(k, v)); ctrl.push((k, v)); check_structure(&map); @@ -935,7 +944,7 @@ mod test_treemap { assert!(b.insert(0, 5)); assert!(a < b); assert!(a.insert(0, 7)); - assert!(!(a < b) && !(b < a)); + assert!(!(a < b) && b < a); assert!(b.insert(-2, 0)); assert!(b < a); assert!(a.insert(-5, 2)); diff --git a/src/libextra/uv_ll.rs b/src/libextra/uv_ll.rs index db960f334fdc..69ff10078407 100644 --- a/src/libextra/uv_ll.rs +++ b/src/libextra/uv_ll.rs @@ -1046,7 +1046,7 @@ pub unsafe fn ip4_name(src: &sockaddr_in) -> ~str { // ipv4 addr max size: 15 + 1 trailing null byte let dst: ~[u8] = ~[0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8, 0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8]; - do vec::as_imm_buf(dst) |dst_buf, size| { + do dst.as_imm_buf |dst_buf, size| { rust_uv_ip4_name(to_unsafe_ptr(src), dst_buf, size as libc::size_t); // seems that checking the result of uv_ip4_name @@ -1066,7 +1066,7 @@ pub unsafe fn ip6_name(src: &sockaddr_in6) -> ~str { 0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8, 0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8, 0u8,0u8,0u8,0u8,0u8,0u8]; - do vec::as_imm_buf(dst) |dst_buf, size| { + do dst.as_imm_buf |dst_buf, size| { let src_unsafe_ptr = to_unsafe_ptr(src); let result = rust_uv_ip6_name(src_unsafe_ptr, dst_buf, size as libc::size_t); diff --git a/src/librust/rust.rs b/src/librust/rust.rs index 30b980a2f858..71504b6498bf 100644 --- a/src/librust/rust.rs +++ b/src/librust/rust.rs @@ -13,7 +13,7 @@ // FIXME #2238 Make run only accept source that emits an executable #[link(name = "rust", - vers = "0.7", + vers = "0.8-pre", uuid = "4a24da33-5cc8-4037-9352-2cbe9bd9d27c", url = "https://github.com/mozilla/rust/tree/master/src/rust")]; @@ -60,7 +60,7 @@ struct Command<'self> { usage_full: UsageSource<'self>, } -static commands: &'static [Command<'static>] = &[ +static COMMANDS: &'static [Command<'static>] = &[ Command{ cmd: "build", action: CallMain("rustc", rustc::main), @@ -122,7 +122,7 @@ fn rustc_help() { } fn find_cmd(command_string: &str) -> Option { - do commands.iter().find_ |command| { + do COMMANDS.iter().find_ |command| { command.cmd == command_string }.map_consume(|x| copy *x) } @@ -197,7 +197,7 @@ fn do_command(command: &Command, args: &[~str]) -> ValidUsage { } fn usage() { - static indent: uint = 8; + static INDENT: uint = 8; io::print( "The rust tool is a convenience for managing rust source code.\n\ @@ -209,8 +209,8 @@ fn usage() { \n" ); - for commands.iter().advance |command| { - let padding = " ".repeat(indent - command.cmd.len()); + for COMMANDS.iter().advance |command| { + let padding = " ".repeat(INDENT - command.cmd.len()); io::println(fmt!(" %s%s%s", command.cmd, padding, command.usage_line)); } diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 61d39421b7fd..a7abc6190803 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -893,7 +893,7 @@ pub fn link_args(sess: Session, // Add all the link args for external crates. do cstore::iter_crate_data(cstore) |crate_num, _| { let link_args = csearch::get_link_args_for_crate(cstore, crate_num); - do vec::consume(link_args) |_, link_arg| { + for link_args.consume_iter().advance |link_arg| { args.push(link_arg); } } diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index a32f54fe7bba..3c5075474488 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -123,10 +123,10 @@ pub fn build_configuration(sess: Session, argv0: @str, input: &input) -> // Convert strings provided as --cfg [cfgspec] into a crate_cfg fn parse_cfgspecs(cfgspecs: ~[~str], demitter: diagnostic::Emitter) -> ast::crate_cfg { - do vec::map_consume(cfgspecs) |s| { + do cfgspecs.consume_iter().transform |s| { let sess = parse::new_parse_sess(Some(demitter)); parse::parse_meta_from_source_str(@"cfgspec", s.to_managed(), ~[], sess) - } + }.collect() } pub enum input { diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index b1d4820f062e..0d4d96b3b2b3 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -10,10 +10,9 @@ use std::option; -use std::vec; use syntax::{ast, fold, attr}; -type in_cfg_pred = @fn(attrs: ~[ast::attribute]) -> bool; +type in_cfg_pred = @fn(attrs: &[ast::attribute]) -> bool; struct Context { in_cfg: in_cfg_pred @@ -51,8 +50,7 @@ fn filter_item(cx: @Context, item: @ast::item) -> if item_in_cfg(cx, item) { option::Some(item) } else { option::None } } -fn filter_view_item(cx: @Context, view_item: @ast::view_item - )-> Option<@ast::view_item> { +fn filter_view_item<'r>(cx: @Context, view_item: &'r ast::view_item)-> Option<&'r ast::view_item> { if view_item_in_cfg(cx, view_item) { option::Some(view_item) } else { @@ -61,13 +59,15 @@ fn filter_view_item(cx: @Context, view_item: @ast::view_item } fn fold_mod(cx: @Context, m: &ast::_mod, fld: @fold::ast_fold) -> ast::_mod { - let filtered_items = - m.items.filter_mapped(|a| filter_item(cx, *a)); - let filtered_view_items = - m.view_items.filter_mapped(|a| filter_view_item(cx, *a)); + let filtered_items = do m.items.iter().filter_map |a| { + filter_item(cx, *a).chain(|x| fld.fold_item(x)) + }.collect(); + let filtered_view_items = do m.view_items.iter().filter_map |a| { + filter_view_item(cx, a).map(|&x| fld.fold_view_item(x)) + }.collect(); ast::_mod { - view_items: filtered_view_items.map(|x| fld.fold_view_item(*x)), - items: vec::filter_map(filtered_items, |x| fld.fold_item(x)) + view_items: filtered_view_items, + items: filtered_items } } @@ -83,14 +83,14 @@ fn fold_foreign_mod( nm: &ast::foreign_mod, fld: @fold::ast_fold ) -> ast::foreign_mod { - let filtered_items = - nm.items.filter_mapped(|a| filter_foreign_item(cx, *a)); - let filtered_view_items = - nm.view_items.filter_mapped(|a| filter_view_item(cx, *a)); + let filtered_items = nm.items.iter().filter_map(|a| filter_foreign_item(cx, *a)).collect(); + let filtered_view_items = do nm.view_items.iter().filter_map |a| { + filter_view_item(cx, a).map(|&x| fld.fold_view_item(x)) + }.collect(); ast::foreign_mod { sort: nm.sort, abis: nm.abis, - view_items: filtered_view_items.iter().transform(|x| fld.fold_view_item(*x)).collect(), + view_items: filtered_view_items, items: filtered_items } } @@ -98,12 +98,14 @@ fn fold_foreign_mod( fn fold_item_underscore(cx: @Context, item: &ast::item_, fld: @fold::ast_fold) -> ast::item_ { let item = match *item { - ast::item_impl(ref a, b, c, ref methods) => { - let methods = methods.filtered(|m| method_in_cfg(cx, *m) ); - ast::item_impl(/*bad*/ copy *a, b, c, methods) + ast::item_impl(ref a, ref b, ref c, ref methods) => { + let methods = methods.iter().filter(|m| method_in_cfg(cx, **m)) + .transform(|x| *x).collect(); + ast::item_impl(/*bad*/ copy *a, /*bad*/ copy *b, /*bad*/ copy *c, methods) } ast::item_trait(ref a, ref b, ref methods) => { - let methods = methods.filtered(|m| trait_method_in_cfg(cx, m) ); + let methods = methods.iter().filter(|m| trait_method_in_cfg(cx, *m) ) + .transform(|x| /* bad */copy *x).collect(); ast::item_trait(/*bad*/copy *a, /*bad*/copy *b, methods) } ref item => /*bad*/ copy *item @@ -134,19 +136,12 @@ fn fold_block( b: &ast::blk_, fld: @fold::ast_fold ) -> ast::blk_ { - let filtered_stmts = - b.stmts.filter_mapped(|a| filter_stmt(cx, *a)); - let filtered_view_items = - b.view_items.filter_mapped(|a| filter_view_item(cx, *a)); - let filtered_view_items = - filtered_view_items.map(|x| fld.fold_view_item(*x)); - let mut resulting_stmts = ~[]; - for filtered_stmts.iter().advance |stmt| { - match fld.fold_stmt(*stmt) { - None => {} - Some(stmt) => resulting_stmts.push(stmt), - } - } + let resulting_stmts = do b.stmts.iter().filter_map |a| { + filter_stmt(cx, *a).chain(|stmt| fld.fold_stmt(stmt)) + }.collect(); + let filtered_view_items = do b.view_items.iter().filter_map |a| { + filter_view_item(cx, a).map(|&x| fld.fold_view_item(x)) + }.collect(); ast::blk_ { view_items: filtered_view_items, stmts: resulting_stmts, @@ -164,8 +159,8 @@ fn foreign_item_in_cfg(cx: @Context, item: @ast::foreign_item) -> bool { return (cx.in_cfg)(/*bad*/copy item.attrs); } -fn view_item_in_cfg(cx: @Context, item: @ast::view_item) -> bool { - return (cx.in_cfg)(/*bad*/copy item.attrs); +fn view_item_in_cfg(cx: @Context, item: &ast::view_item) -> bool { + return (cx.in_cfg)(item.attrs); } fn method_in_cfg(cx: @Context, meth: @ast::method) -> bool { @@ -193,11 +188,13 @@ pub fn metas_in_cfg(cfg: &[@ast::meta_item], // Pull the inner meta_items from the #[cfg(meta_item, ...)] attributes, // so we can match against them. This is the list of configurations for // which the item is valid - let cfg_metas = vec::filter_map(cfg_metas, |i| attr::get_meta_item_list(i)); + let cfg_metas = cfg_metas.consume_iter() + .filter_map(|i| attr::get_meta_item_list(i)) + .collect::<~[~[@ast::meta_item]]>(); if cfg_metas.iter().all(|c| c.is_empty()) { return true; } - cfg_metas.iter().any_(|cfg_meta| { + 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 diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs index 735fe54f3480..45169a2f6566 100644 --- a/src/librustc/front/std_inject.rs +++ b/src/librustc/front/std_inject.rs @@ -18,7 +18,7 @@ use syntax::codemap::dummy_sp; use syntax::codemap; use syntax::fold; -static STD_VERSION: &'static str = "0.7"; +static STD_VERSION: &'static str = "0.8-pre"; pub fn maybe_inject_libstd_ref(sess: Session, crate: @ast::crate) -> @ast::crate { @@ -41,7 +41,7 @@ fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate { let precursor = @fold::AstFoldFns { fold_crate: |crate, span, fld| { let n1 = sess.next_node_id(); - let vi1 = @ast::view_item { + let vi1 = ast::view_item { node: ast::view_item_extern_mod( sess.ident_of("std"), ~[], n1), attrs: ~[ @@ -75,7 +75,7 @@ fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate { fold_mod: |module, fld| { let n2 = sess.next_node_id(); - let prelude_path = @ast::Path { + let prelude_path = ast::Path { span: dummy_sp(), global: false, idents: ~[ @@ -87,7 +87,7 @@ fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate { }; let vp = @spanned(ast::view_path_glob(prelude_path, n2)); - let vi2 = @ast::view_item { node: ast::view_item_use(~[vp]), + let vi2 = ast::view_item { node: ast::view_item_use(~[vp]), attrs: ~[], vis: ast::private, span: dummy_sp() }; diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index 41c70c4c5b41..7137272acda5 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -17,7 +17,7 @@ use front::config; use std::vec; use syntax::ast_util::*; use syntax::attr; -use syntax::codemap::{dummy_sp, span, ExpandedFrom, CallInfo, NameAndSpan}; +use syntax::codemap::{dummy_sp, span, ExpnInfo, NameAndSpan}; use syntax::codemap; use syntax::ext::base::ExtCtxt; use syntax::fold; @@ -72,13 +72,13 @@ fn generate_test_harness(sess: session::Session, }; let ext_cx = cx.ext_cx; - ext_cx.bt_push(ExpandedFrom(CallInfo { + ext_cx.bt_push(ExpnInfo { call_site: dummy_sp(), callee: NameAndSpan { name: @"test", span: None } - })); + }); let precursor = @fold::AstFoldFns { fold_crate: fold::wrap(|a,b| fold_crate(cx, a, b) ), @@ -109,9 +109,11 @@ fn fold_mod(cx: @mut TestCtxt, fn nomain(cx: @mut TestCtxt, item: @ast::item) -> @ast::item { if !*cx.sess.building_library { - @ast::item{attrs: item.attrs.filtered(|attr| { - "main" != attr::get_attr_name(attr) - }),.. copy *item} + @ast::item{ + attrs: do item.attrs.iter().filter_map |attr| { + if "main" != attr::get_attr_name(attr) {Some(*attr)} else {None} + }.collect(), + .. copy *item} } else { item } } @@ -229,10 +231,10 @@ fn is_ignored(cx: @mut TestCtxt, i: @ast::item) -> bool { let ignoreattrs = attr::find_attrs_by_name(i.attrs, "ignore"); let ignoreitems = attr::attr_metas(ignoreattrs); return if !ignoreitems.is_empty() { - let cfg_metas = - vec::concat( - vec::filter_map(ignoreitems, - |i| attr::get_meta_item_list(i))); + let cfg_metas = ignoreitems.consume_iter() + .filter_map(|i| attr::get_meta_item_list(i)) + .collect::<~[~[@ast::meta_item]]>() + .concat_vec(); config::metas_in_cfg(/*bad*/copy cx.crate.node.config, cfg_metas) } else { false @@ -270,8 +272,8 @@ mod __test { */ -fn mk_std(cx: &TestCtxt) -> @ast::view_item { - let vers = ast::lit_str(@"0.7"); +fn mk_std(cx: &TestCtxt) -> ast::view_item { + let vers = ast::lit_str(@"0.8-pre"); let vers = nospan(vers); let mi = ast::meta_name_value(@"vers", vers); let mi = nospan(mi); @@ -285,13 +287,12 @@ fn mk_std(cx: &TestCtxt) -> @ast::view_item { ast::view_item_extern_mod(id_std, ~[@mi], cx.sess.next_node_id()) }; - let vi = ast::view_item { + ast::view_item { node: vi, attrs: ~[], vis: ast::public, span: dummy_sp() - }; - return @vi; + } } fn mk_test_module(cx: &TestCtxt) -> @ast::item { @@ -308,7 +309,7 @@ fn mk_test_module(cx: &TestCtxt) -> @ast::item { let mainfn = (quote_item!( pub fn main() { #[main]; - extra::test::test_main_static(::std::os::args(), tests); + extra::test::test_main_static(::std::os::args(), TESTS); } )).get(); @@ -341,16 +342,16 @@ fn nospan(t: T) -> codemap::spanned { codemap::spanned { node: t, span: dummy_sp() } } -fn path_node(ids: ~[ast::ident]) -> @ast::Path { - @ast::Path { span: dummy_sp(), +fn path_node(ids: ~[ast::ident]) -> ast::Path { + ast::Path { span: dummy_sp(), global: false, idents: ids, rp: None, types: ~[] } } -fn path_node_global(ids: ~[ast::ident]) -> @ast::Path { - @ast::Path { span: dummy_sp(), +fn path_node_global(ids: ~[ast::ident]) -> ast::Path { + ast::Path { span: dummy_sp(), global: true, idents: ids, rp: None, @@ -365,7 +366,7 @@ fn mk_tests(cx: &TestCtxt) -> @ast::item { let test_descs = mk_test_descs(cx); (quote_item!( - pub static tests : &'static [self::extra::test::TestDescAndFn] = + pub static TESTS : &'static [self::extra::test::TestDescAndFn] = $test_descs ; )).get() diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 2a712b075647..8c62f4dbbe35 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -136,7 +136,7 @@ fn visit_crate(e: &Env, c: &ast::crate) { } } -fn visit_view_item(e: @mut Env, i: @ast::view_item) { +fn visit_view_item(e: @mut Env, i: &ast::view_item) { match i.node { ast::view_item_extern_mod(ident, ref meta_items, id) => { debug!("resolving extern mod stmt. ident: %?, meta: %?", diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 3413cd341ba4..bb1834dc5c8f 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -102,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.iter().any_(|x| x == &lib) { return false; } + if cstore.used_libraries.iter().any(|x| x == &lib) { return false; } cstore.used_libraries.push(lib); true } diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 2c7a991f6146..1e508d081318 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -1141,7 +1141,7 @@ fn list_crate_attributes(intr: @ident_interner, md: ebml::Doc, hash: &str, let r = get_attributes(md); for r.iter().advance |attr| { - out.write_str(fmt!("%s\n", pprust::attribute_to_str(*attr, intr))); + out.write_str(fmt!("%s\n", pprust::attribute_to_str(attr, intr))); } out.write_str("\n\n"); diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 77a8d1792dbc..a9f3200af128 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1003,7 +1003,7 @@ fn encode_info_for_item(ecx: &EncodeContext, index); } } - item_impl(ref generics, opt_trait, ty, ref methods) => { + item_impl(ref generics, ref opt_trait, ref ty, ref methods) => { add_to_index(); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); @@ -1014,7 +1014,7 @@ 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, bounds, _) if path.idents.len() == 1 => { + ast::ty_path(ref path, ref bounds, _) if path.idents.len() == 1 => { assert!(bounds.is_none()); encode_impl_type_basename(ecx, ebml_w, ast_util::path_to_ident(path)); diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index c6d7314f1cd9..72b6f8e1c805 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -291,16 +291,16 @@ fn encode_ast(ebml_w: &mut writer::Encoder, item: ast::inlined_item) { // inlined items. fn simplify_ast(ii: &ast::inlined_item) -> ast::inlined_item { fn drop_nested_items(blk: &ast::blk_, fld: @fold::ast_fold) -> ast::blk_ { - let stmts_sans_items = do blk.stmts.filtered |stmt| { + let stmts_sans_items = do blk.stmts.iter().filter_map |stmt| { match stmt.node { ast::stmt_expr(_, _) | ast::stmt_semi(_, _) | - ast::stmt_decl(@codemap::spanned { node: ast::decl_local(_), - span: _}, _) => true, - ast::stmt_decl(@codemap::spanned { node: ast::decl_item(_), - span: _}, _) => false, + ast::stmt_decl(@codemap::spanned { node: ast::decl_local(_), span: _}, _) + => Some(*stmt), + ast::stmt_decl(@codemap::spanned { node: ast::decl_item(_), span: _}, _) + => None, ast::stmt_mac(*) => fail!("unexpanded macro in astencode") } - }; + }.collect(); let blk_sans_items = ast::blk_ { view_items: ~[], // I don't know if we need the view_items here, // but it doesn't break tests! diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 7d667c2043c1..2e3813f57e08 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -538,12 +538,13 @@ impl BorrowckCtxt { move_data::MoveExpr(expr) => { let expr_ty = ty::expr_ty_adjusted(self.tcx, expr); + let suggestion = move_suggestion(self.tcx, expr_ty, + "moved by default (use `copy` to override)"); self.tcx.sess.span_note( expr.span, - fmt!("`%s` moved here because it has type `%s`, \ - which is moved by default (use `copy` to override)", + fmt!("`%s` moved here because it has type `%s`, which is %s", self.loan_path_to_str(moved_lp), - expr_ty.user_string(self.tcx))); + expr_ty.user_string(self.tcx), suggestion)); } move_data::MovePat(pat) => { @@ -557,12 +558,28 @@ impl BorrowckCtxt { } move_data::Captured(expr) => { + let expr_ty = ty::expr_ty_adjusted(self.tcx, expr); + let suggestion = move_suggestion(self.tcx, expr_ty, + "moved by default (make a copy and \ + capture that instead to override)"); self.tcx.sess.span_note( expr.span, - fmt!("`%s` moved into closure environment here \ - because its type is moved by default \ - (make a copy and capture that instead to override)", - self.loan_path_to_str(moved_lp))); + fmt!("`%s` moved into closure environment here because it \ + has type `%s`, which is %s", + self.loan_path_to_str(moved_lp), + expr_ty.user_string(self.tcx), suggestion)); + } + } + + fn move_suggestion(tcx: ty::ctxt, ty: ty::t, default_msg: &'static str) + -> &'static str { + match ty::get(ty).sty { + ty::ty_closure(ref cty) if cty.sigil == ast::BorrowedSigil => + "a non-copyable stack closure (capture it in a new closure, \ + e.g. `|x| f(x)`, to override)", + _ if !ty::type_is_copyable(tcx, ty) => + "non-copyable (perhaps you meant to use clone()?)", + _ => default_msg, } } } diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs index 97fd6ca5cc43..73adade7a5d7 100644 --- a/src/librustc/middle/borrowck/move_data.rs +++ b/src/librustc/middle/borrowck/move_data.rs @@ -506,7 +506,7 @@ impl FlowedMoveData { for self.dfcx_moves.each_bit_on_entry_frozen(id) |index| { let move = &self.move_data.moves[index]; let moved_path = move.path; - if base_indices.iter().any_(|x| x == &moved_path) { + if base_indices.iter().any(|x| x == &moved_path) { // Scenario 1 or 2: `loan_path` or some base path of // `loan_path` was moved. if !f(move, self.move_data.path(moved_path).loan_path) { @@ -535,7 +535,7 @@ impl FlowedMoveData { -> bool { //! True if `id` is the id of the LHS of an assignment - self.move_data.assignee_ids.iter().any_(|x| x == &id) + self.move_data.assignee_ids.iter().any(|x| x == &id) } pub fn each_assignment_of(&self, diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 59918137467a..26a03b362e35 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -112,7 +112,7 @@ pub fn check_expr(sess: Session, "` in a constant expression"); } } - expr_path(pth) => { + expr_path(ref pth) => { // NB: In the future you might wish to relax this slightly // to handle on-demand instantiation of functions via // foo:: in a const. Currently that is only done on @@ -224,7 +224,7 @@ pub fn check_item_recursion(sess: Session, (visitor.visit_item)(it, (env, visitor)); fn visit_item(it: @item, (env, v): (env, visit::vt)) { - if env.idstack.iter().any_(|x| x == &(it.id)) { + if env.idstack.iter().any(|x| x == &(it.id)) { env.sess.span_fatal(env.root_it.span, "recursive constant"); } env.idstack.push(it.id); diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 72896258b2d3..0baeb8ce57c6 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -95,7 +95,7 @@ pub fn check_expr(cx: @MatchCheckCtxt, ex: @expr, (s, v): ((), visit::vt<()>)) { } _ => { /* We assume only enum types can be uninhabited */ } } - let arms = vec::concat(arms.filter_mapped(unguarded_pat)); + let arms = arms.iter().filter_map(unguarded_pat).collect::<~[~[@pat]]>().concat_vec(); if arms.is_empty() { cx.tcx.sess.span_err(ex.span, "non-exhaustive patterns"); } else { @@ -265,7 +265,7 @@ pub fn is_useful(cx: &MatchCheckCtxt, m: &matrix, v: &[@pat]) -> useful { } Some(ref ctor) => { match is_useful(cx, - &m.filter_mapped(|r| default(cx, *r)), + &m.iter().filter_map(|r| default(cx, *r)).collect::(), v.tail()) { useful_ => useful(left_ty, /*bad*/copy *ctor), ref u => (/*bad*/copy *u) @@ -287,7 +287,7 @@ pub fn is_useful_specialized(cx: &MatchCheckCtxt, arity: uint, lty: ty::t) -> useful { - let ms = m.filter_mapped(|r| specialize(cx, *r, &ctor, arity, lty)); + let ms = m.iter().filter_map(|r| specialize(cx, *r, &ctor, arity, lty)).collect::(); let could_be_useful = is_useful( cx, &ms, specialize(cx, v, &ctor, arity, lty).get()); match could_be_useful { @@ -371,7 +371,7 @@ pub fn missing_ctor(cx: &MatchCheckCtxt, let variants = ty::enum_variants(cx.tcx, eid); if found.len() != (*variants).len() { for (*variants).iter().advance |v| { - if !found.iter().any_(|x| x == &(variant(v.id))) { + if !found.iter().any(|x| x == &(variant(v.id))) { return Some(variant(v.id)); } } @@ -397,14 +397,14 @@ pub fn missing_ctor(cx: &MatchCheckCtxt, ty::ty_unboxed_vec(*) | ty::ty_evec(*) => { // Find the lengths and slices of all vector patterns. - let vec_pat_lens = do m.filter_mapped |r| { + let vec_pat_lens = do m.iter().filter_map |r| { match r[0].node { pat_vec(ref before, ref slice, ref after) => { Some((before.len() + after.len(), slice.is_some())) } _ => None } - }; + }.collect::<~[(uint, bool)]>(); // Sort them by length such that for patterns of the same length, // those with a destructured slice come first. @@ -805,13 +805,13 @@ pub fn is_refutable(cx: &MatchCheckCtxt, pat: &pat) -> bool { } pat_lit(_) | pat_range(_, _) => { true } pat_struct(_, ref fields, _) => { - fields.iter().any_(|f| is_refutable(cx, f.pat)) + fields.iter().any(|f| is_refutable(cx, f.pat)) } pat_tup(ref elts) => { - elts.iter().any_(|elt| is_refutable(cx, *elt)) + elts.iter().any(|elt| is_refutable(cx, *elt)) } pat_enum(_, Some(ref args)) => { - args.iter().any_(|a| is_refutable(cx, *a)) + args.iter().any(|a| is_refutable(cx, *a)) } pat_enum(_,_) => { false } pat_vec(*) => { true } diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index ac18a9b76cf9..e054b84984d1 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -341,14 +341,14 @@ impl DataFlowContext { let entry_str = bits_to_str(on_entry); let gens = self.gens.slice(start, end); - let gens_str = if gens.iter().any_(|&u| u != 0) { + let gens_str = if gens.iter().any(|&u| u != 0) { fmt!(" gen: %s", bits_to_str(gens)) } else { ~"" }; let kills = self.kills.slice(start, end); - let kills_str = if kills.iter().any_(|&u| u != 0) { + let kills_str = if kills.iter().any(|&u| u != 0) { fmt!(" kill: %s", bits_to_str(kills)) } else { ~"" @@ -643,7 +643,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { self.walk_opt_expr(o_e, in_out, loop_scopes); // is this a return from a `for`-loop closure? - match loop_scopes.iter().position_(|s| s.loop_kind == ForLoop) { + match loop_scopes.iter().position(|s| s.loop_kind == ForLoop) { Some(i) => { // if so, add the in_out bits to the state // upon exit. Remember that we cannot count @@ -916,7 +916,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { Some(_) => { match self.tcx().def_map.find(&expr.id) { Some(&ast::def_label(loop_id)) => { - match loop_scopes.iter().position_(|l| l.loop_id == loop_id) { + match loop_scopes.iter().position(|l| l.loop_id == loop_id) { Some(i) => i, None => { self.tcx().sess.span_bug( diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index a207985e64c8..a9454d1b2309 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -117,7 +117,7 @@ fn check_item(item: @item, (cx, visitor): (Context, visit::vt)) { // If this is a destructor, check kinds. if !attrs_contains_name(item.attrs, "unsafe_destructor") { match item.node { - item_impl(_, Some(trait_ref), self_type, _) => { + item_impl(_, Some(ref trait_ref), ref self_type, _) => { match cx.tcx.def_map.find(&trait_ref.ref_id) { None => cx.tcx.sess.bug("trait ref not in def map!"), Some(&trait_def) => { @@ -125,7 +125,7 @@ fn check_item(item: @item, (cx, visitor): (Context, visit::vt)) { if cx.tcx.lang_items.drop_trait() == trait_def_id { // Yes, it's a destructor. match self_type.node { - ty_path(_, bounds, path_node_id) => { + ty_path(_, ref bounds, path_node_id) => { assert!(bounds.is_none()); let struct_def = cx.tcx.def_map.get_copy( &path_node_id); @@ -198,8 +198,9 @@ fn with_appropriate_checker(cx: Context, id: node_id, fn check_for_bare(cx: Context, fv: @freevar_entry) { cx.tcx.sess.span_err( fv.span, - "attempted dynamic environment capture"); - } + "can't capture dynamic environment in a fn item; \ + use the || { ... } closure form instead"); + } // same check is done in resolve.rs, but shouldn't be done let fty = ty::node_id_to_type(cx.tcx, id); match ty::get(fty).sty { @@ -320,7 +321,7 @@ pub fn check_expr(e: @expr, (cx, v): (Context, visit::vt)) { visit::visit_expr(e, (cx, v)); } -fn check_ty(aty: @Ty, (cx, v): (Context, visit::vt)) { +fn check_ty(aty: &Ty, (cx, v): (Context, visit::vt)) { match aty.node { ty_path(_, _, id) => { let r = cx.tcx.node_type_substs.find(&id); @@ -535,7 +536,7 @@ pub fn check_cast_for_escaping_regions( // Check, based on the region associated with the trait, whether it can // possibly escape the enclosing fn item (note that all type parameters // must have been declared on the enclosing fn item). - if target_regions.iter().any_(|r| is_re_scope(*r)) { + if target_regions.iter().any(|r| is_re_scope(*r)) { return; /* case (1) */ } @@ -550,7 +551,7 @@ pub fn check_cast_for_escaping_regions( |_r| { // FIXME(#5723) --- turn this check on once &Objects are usable // - // if !target_regions.iter().any_(|t_r| is_subregion_of(cx, *t_r, r)) { + // if !target_regions.iter().any(|t_r| is_subregion_of(cx, *t_r, r)) { // cx.tcx.sess.span_err( // source.span, // fmt!("source contains borrowed pointer with lifetime \ @@ -564,7 +565,7 @@ pub fn check_cast_for_escaping_regions( |ty| { match ty::get(ty).sty { ty::ty_param(source_param) => { - if target_params.iter().any_(|x| x == &source_param) { + if target_params.iter().any(|x| x == &source_param) { /* case (2) */ } else { check_durable(cx.tcx, ty, source.span); /* case (3) */ diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 0e9361193b0a..d4d1997a56f2 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -63,33 +63,34 @@ pub enum LangItem { FailFnLangItem, // 24 FailBoundsCheckFnLangItem, // 25 ExchangeMallocFnLangItem, // 26 - ClosureExchangeMallocFnLangItem, // 27 - ExchangeFreeFnLangItem, // 28 - MallocFnLangItem, // 29 - FreeFnLangItem, // 30 - BorrowAsImmFnLangItem, // 31 - BorrowAsMutFnLangItem, // 32 - ReturnToMutFnLangItem, // 33 - CheckNotBorrowedFnLangItem, // 34 - StrDupUniqFnLangItem, // 35 - RecordBorrowFnLangItem, // 36 - UnrecordBorrowFnLangItem, // 37 + VectorExchangeMallocFnLangItem, // 27 + ClosureExchangeMallocFnLangItem, // 28 + ExchangeFreeFnLangItem, // 29 + MallocFnLangItem, // 30 + FreeFnLangItem, // 31 + BorrowAsImmFnLangItem, // 32 + BorrowAsMutFnLangItem, // 33 + ReturnToMutFnLangItem, // 34 + CheckNotBorrowedFnLangItem, // 35 + StrDupUniqFnLangItem, // 36 + RecordBorrowFnLangItem, // 37 + UnrecordBorrowFnLangItem, // 38 - StartFnLangItem, // 38 + StartFnLangItem, // 39 - TyDescStructLangItem, // 39 - TyVisitorTraitLangItem, // 40 - OpaqueStructLangItem, // 41 + TyDescStructLangItem, // 40 + TyVisitorTraitLangItem, // 41 + OpaqueStructLangItem, // 42 } pub struct LanguageItems { - items: [Option, ..42] + items: [Option, ..43] } impl LanguageItems { pub fn new() -> LanguageItems { LanguageItems { - items: [ None, ..42 ] + items: [ None, ..43 ] } } @@ -129,23 +130,24 @@ impl LanguageItems { 24 => "fail_", 25 => "fail_bounds_check", 26 => "exchange_malloc", - 27 => "closure_exchange_malloc", - 28 => "exchange_free", - 29 => "malloc", - 30 => "free", - 31 => "borrow_as_imm", - 32 => "borrow_as_mut", - 33 => "return_to_mut", - 34 => "check_not_borrowed", - 35 => "strdup_uniq", - 36 => "record_borrow", - 37 => "unrecord_borrow", + 27 => "vector_exchange_malloc", + 28 => "closure_exchange_malloc", + 29 => "exchange_free", + 30 => "malloc", + 31 => "free", + 32 => "borrow_as_imm", + 33 => "borrow_as_mut", + 34 => "return_to_mut", + 35 => "check_not_borrowed", + 36 => "strdup_uniq", + 37 => "record_borrow", + 38 => "unrecord_borrow", - 38 => "start", + 39 => "start", - 39 => "ty_desc", - 40 => "ty_visitor", - 41 => "opaque", + 40 => "ty_desc", + 41 => "ty_visitor", + 42 => "opaque", _ => "???" } @@ -238,6 +240,9 @@ impl LanguageItems { pub fn exchange_malloc_fn(&self) -> def_id { self.items[ExchangeMallocFnLangItem as uint].get() } + pub fn vector_exchange_malloc_fn(&self) -> def_id { + self.items[VectorExchangeMallocFnLangItem as uint].get() + } pub fn closure_exchange_malloc_fn(&self) -> def_id { self.items[ClosureExchangeMallocFnLangItem as uint].get() } @@ -331,6 +336,7 @@ impl<'self> LanguageItemCollector<'self> { item_refs.insert(@"fail_bounds_check", FailBoundsCheckFnLangItem as uint); item_refs.insert(@"exchange_malloc", ExchangeMallocFnLangItem as uint); + item_refs.insert(@"vector_exchange_malloc", VectorExchangeMallocFnLangItem as uint); item_refs.insert(@"closure_exchange_malloc", ClosureExchangeMallocFnLangItem as uint); item_refs.insert(@"exchange_free", ExchangeFreeFnLangItem as uint); item_refs.insert(@"malloc", MallocFnLangItem as uint); diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index ce09f790ef45..0fc19ffd78e5 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -14,7 +14,6 @@ use middle::ty; use middle::pat_util; use util::ppaux::{ty_to_str}; -use std::char; use std::cmp; use std::hashmap::HashMap; use std::i16; @@ -25,7 +24,6 @@ use std::u16; use std::u32; use std::u64; use std::u8; -use std::vec; use extra::smallintmap::SmallIntMap; use syntax::attr; use syntax::codemap::span; @@ -80,6 +78,7 @@ pub enum lint { non_implicitly_copyable_typarams, deprecated_pattern, non_camel_case_types, + non_uppercase_statics, type_limits, default_methods, unused_unsafe, @@ -198,6 +197,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[ default: allow }), + ("non_uppercase_statics", + LintSpec { + lint: non_uppercase_statics, + desc: "static constants should have uppercase identifiers", + default: warn + }), + ("managed_heap_memory", LintSpec { lint: managed_heap_memory, @@ -741,9 +747,9 @@ fn check_item_ctypes(cx: &Context, it: &ast::item) { fn check_foreign_fn(cx: &Context, decl: &ast::fn_decl) { for decl.inputs.iter().advance |in| { - check_ty(cx, in.ty); + check_ty(cx, &in.ty); } - check_ty(cx, decl.output) + check_ty(cx, &decl.output) } match it.node { @@ -753,7 +759,7 @@ fn check_item_ctypes(cx: &Context, it: &ast::item) { ast::foreign_item_fn(ref decl, _, _) => { check_foreign_fn(cx, decl); } - ast::foreign_item_static(t, _) => { check_ty(cx, t); } + ast::foreign_item_static(ref t, _) => { check_ty(cx, t); } } } } @@ -854,7 +860,10 @@ fn check_item_non_camel_case_types(cx: &Context, it: &ast::item) { let ident = cx.sess.str_of(ident); assert!(!ident.is_empty()); let ident = ident.trim_chars(&'_'); - char::is_uppercase(ident.char_at(0)) && + + // start with a non-lowercase letter rather than non-uppercase + // ones (some scripts don't have a concept of upper/lowercase) + !ident.char_at(0).is_lowercase() && !ident.contains_char('_') } @@ -881,6 +890,23 @@ fn check_item_non_camel_case_types(cx: &Context, it: &ast::item) { } } +fn check_item_non_uppercase_statics(cx: &Context, it: &ast::item) { + match it.node { + // only check static constants + ast::item_static(_, ast::m_imm, _) => { + let s = cx.tcx.sess.str_of(it.ident); + // check for lowercase letters rather than non-uppercase + // ones (some scripts don't have a concept of + // upper/lowercase) + if s.iter().any(|c| c.is_lowercase()) { + cx.span_lint(non_uppercase_statics, it.span, + "static constant should have an uppercase identifier"); + } + } + _ => {} + } +} + fn lint_unused_unsafe() -> visit::vt<@mut Context> { visit::mk_vt(@visit::Visitor { visit_expr: |e, (cx, vt): (@mut Context, visit::vt<@mut Context>)| { @@ -940,10 +966,6 @@ fn lint_unused_mut() -> visit::vt<@mut Context> { visit_fn_decl(cx, &tm.decl); visit::visit_ty_method(tm, (cx, vt)); }, - visit_struct_method: |sm, (cx, vt)| { - visit_fn_decl(cx, &sm.decl); - visit::visit_struct_method(sm, (cx, vt)); - }, visit_trait_method: |tm, (cx, vt)| { match *tm { ast::required(ref tm) => visit_fn_decl(cx, &tm.decl), @@ -960,7 +982,7 @@ fn lint_session() -> visit::vt<@mut Context> { match cx.tcx.sess.lints.pop(&id) { None => {}, Some(l) => { - do vec::consume(l) |_, (lint, span, msg)| { + for l.consume_iter().advance |(lint, span, msg)| { cx.span_lint(lint, span, msg) } } @@ -1016,21 +1038,13 @@ fn lint_missing_doc() -> visit::vt<@mut Context> { // If we have doc(hidden), nothing to do if cx.doc_hidden { return } // If we're documented, nothing to do - if attrs.iter().any_(|a| a.node.is_sugared_doc) { return } + if attrs.iter().any(|a| a.node.is_sugared_doc) { return } // otherwise, warn! cx.span_lint(missing_doc, sp, msg); } visit::mk_vt(@visit::Visitor { - visit_struct_method: |m, (cx, vt)| { - if m.vis == ast::public { - check_attrs(cx, m.attrs, m.span, - "missing documentation for a method"); - } - visit::visit_struct_method(m, (cx, vt)); - }, - visit_ty_method: |m, (cx, vt)| { // All ty_method objects are linted about because they're part of a // trait (no visibility) @@ -1143,6 +1157,7 @@ pub fn check_crate(tcx: ty::ctxt, crate: @ast::crate) { } check_item_ctypes(cx, it); check_item_non_camel_case_types(cx, it); + check_item_non_uppercase_statics(cx, it); check_item_default_methods(cx, it); check_item_heap(cx, it); diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index c7d338b1976a..f3d4abcdf310 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -390,8 +390,8 @@ impl VisitContext { // any fields which (1) were not explicitly // specified and (2) have a type that // moves-by-default: - let consume_with = with_fields.iter().any_(|tf| { - !fields.iter().any_(|f| f.node.ident == tf.ident) && + let consume_with = with_fields.iter().any(|tf| { + !fields.iter().any(|f| f.node.ident == tf.ident) && ty::type_moves_by_default(self.tcx, tf.mt.ty) }); diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index f6da8f392cc1..7dd7ae6ec9ae 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -71,10 +71,10 @@ pub fn pat_is_binding_or_wild(dm: resolve::DefMap, pat: @pat) -> bool { } pub fn pat_bindings(dm: resolve::DefMap, pat: @pat, - it: &fn(binding_mode, node_id, span, @Path)) { + it: &fn(binding_mode, node_id, span, &Path)) { for walk_pat(pat) |p| { match p.node { - pat_ident(binding_mode, pth, _) if pat_is_binding(dm, p) => { + pat_ident(binding_mode, ref pth, _) if pat_is_binding(dm, p) => { it(binding_mode, p.id, p.span, pth); } _ => {} diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 5e544dc06e3d..8a2b13419153 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -245,13 +245,21 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, method_id: def_id, name: &ident) = |span, method_id, name| { + // If the method is a default method, we need to use the def_id of + // the default implementation. + // Having to do this this is really unfortunate. + let method_id = match tcx.provided_method_sources.find(&method_id) { + None => method_id, + Some(source) => source.method_id + }; + if method_id.crate == local_crate { let is_private = method_is_private(span, method_id.node); let container_id = local_method_container_id(span, method_id.node); if is_private && (container_id.crate != local_crate || - !privileged_items.iter().any_(|x| x == &(container_id.node))) { + !privileged_items.iter().any(|x| x == &(container_id.node))) { tcx.sess.span_err(span, fmt!("method `%s` is private", token::ident_to_str(name))); @@ -268,7 +276,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, }; // Checks that a private path is in scope. - let check_path: @fn(span: span, def: def, path: @Path) = + let check_path: @fn(span: span, def: def, path: &Path) = |span, def, path| { debug!("checking path"); match def { @@ -279,7 +287,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, def_fn(def_id, _) => { if def_id.crate == local_crate { if local_item_is_private(span, def_id.node) && - !privileged_items.iter().any_(|x| x == &def_id.node) { + !privileged_items.iter().any(|x| x == &def_id.node) { tcx.sess.span_err(span, fmt!("function `%s` is private", token::ident_to_str(path.idents.last()))); @@ -324,7 +332,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, provided(method) if method.vis == private && !privileged_items.iter() - .any_(|x| x == &(trait_id.node)) => { + .any(|x| x == &(trait_id.node)) => { tcx.sess.span_err(span, fmt!("method `%s` is private", token::ident_to_str(&method @@ -409,7 +417,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, base))).sty { ty_struct(id, _) if id.crate != local_crate || !privileged_items.iter() - .any_(|x| x == &(id.node)) => { + .any(|x| x == &(id.node)) => { debug!("(privacy checking) checking field access"); check_field(expr.span, id, ident); } @@ -422,7 +430,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, base))).sty { ty_struct(id, _) if id.crate != local_crate || - !privileged_items.iter().any_(|x| x == &(id.node)) => { + !privileged_items.iter().any(|x| x == &(id.node)) => { match method_map.find(&expr.id) { None => { tcx.sess.span_bug(expr.span, @@ -441,14 +449,14 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, _ => {} } } - expr_path(path) => { + expr_path(ref path) => { check_path(expr.span, tcx.def_map.get_copy(&expr.id), path); } expr_struct(_, ref fields, _) => { match ty::get(ty::expr_ty(tcx, expr)).sty { ty_struct(id, _) => { if id.crate != local_crate || - !privileged_items.iter().any_(|x| x == &(id.node)) { + !privileged_items.iter().any(|x| x == &(id.node)) { for (*fields).iter().advance |field| { debug!("(privacy checking) checking \ field in struct literal"); @@ -459,7 +467,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, } ty_enum(id, _) => { if id.crate != local_crate || - !privileged_items.iter().any_(|x| x == &(id.node)) { + !privileged_items.iter().any(|x| x == &(id.node)) { match tcx.def_map.get_copy(&expr.id) { def_variant(_, variant_id) => { for (*fields).iter().advance |field| { @@ -496,7 +504,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, match ty::get(ty::expr_ty(tcx, operand)).sty { ty_enum(id, _) => { if id.crate != local_crate || - !privileged_items.iter().any_(|x| x == &(id.node)) { + !privileged_items.iter().any(|x| x == &(id.node)) { check_variant(expr.span, id); } } @@ -514,7 +522,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, match ty::get(ty::pat_ty(tcx, pattern)).sty { ty_struct(id, _) => { if id.crate != local_crate || - !privileged_items.iter().any_(|x| x == &(id.node)) { + !privileged_items.iter().any(|x| x == &(id.node)) { for fields.iter().advance |field| { debug!("(privacy checking) checking \ struct pattern"); @@ -525,7 +533,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, } ty_enum(enum_id, _) => { if enum_id.crate != local_crate || - !privileged_items.iter().any_(|x| x == &enum_id.node) { + !privileged_items.iter().any(|x| x == &enum_id.node) { match tcx.def_map.find(&pattern.id) { Some(&def_variant(_, variant_id)) => { for fields.iter().advance |field| { diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 97bad93dc358..70833813cc08 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -141,7 +141,7 @@ impl ReachableContext { } } } - item_impl(ref generics, trait_ref, _, ref methods) => { + item_impl(ref generics, ref trait_ref, _, ref methods) => { // XXX(pcwalton): We conservatively assume any methods // on a trait implementation are reachable, when this // is not the case. We could be more precise by only diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index f65d3ad464c4..e1c43121ec82 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -78,7 +78,7 @@ impl RegionMaps { pub fn relate_free_regions(&mut self, sub: FreeRegion, sup: FreeRegion) { match self.free_region_map.find_mut(&sub) { Some(sups) => { - if !sups.iter().any_(|x| x == &sup) { + if !sups.iter().any(|x| x == &sup) { sups.push(sup); } return; @@ -202,7 +202,7 @@ impl RegionMaps { return true; } - if !queue.iter().any_(|x| x == parent) { + if !queue.iter().any(|x| x == parent) { queue.push(*parent); } } @@ -612,7 +612,7 @@ impl DetermineRpCtxt { ambient_variance: self.ambient_variance, id: self.item_id }; - if !vec.iter().any_(|x| x == &dep) { vec.push(dep); } + if !vec.iter().any(|x| x == &dep) { vec.push(dep); } } // Determines whether a reference to a region that appears in the @@ -651,18 +651,18 @@ impl DetermineRpCtxt { // with &self type, &self is also bound. We detect those last two // cases via flags (anon_implies_rp and self_implies_rp) that are // true when the anon or self region implies RP. - pub fn region_is_relevant(&self, r: Option<@ast::Lifetime>) -> bool { + pub fn region_is_relevant(&self, r: &Option) -> bool { match r { - None => { + &None => { self.anon_implies_rp } - Some(ref l) if l.ident == special_idents::statik => { + &Some(ref l) if l.ident == special_idents::statik => { false } - Some(ref l) if l.ident == special_idents::self_ => { + &Some(ref l) if l.ident == special_idents::self_ => { true } - Some(_) => { + &Some(_) => { false } } @@ -713,10 +713,10 @@ fn determine_rp_in_fn(fk: &visit::fn_kind, do cx.with(cx.item_id, false) { do cx.with_ambient_variance(rv_contravariant) { for decl.inputs.iter().advance |a| { - (visitor.visit_ty)(a.ty, (cx, visitor)); + (visitor.visit_ty)(&a.ty, (cx, visitor)); } } - (visitor.visit_ty)(decl.output, (cx, visitor)); + (visitor.visit_ty)(&decl.output, (cx, visitor)); let generics = visit::generics_of_fn(fk); (visitor.visit_generics)(&generics, (cx, visitor)); (visitor.visit_block)(body, (cx, visitor)); @@ -731,7 +731,7 @@ fn determine_rp_in_ty_method(ty_m: &ast::ty_method, } } -fn determine_rp_in_ty(ty: @ast::Ty, +fn determine_rp_in_ty(ty: &ast::Ty, (cx, visitor): (@mut DetermineRpCtxt, visit::vt<@mut DetermineRpCtxt>)) { // we are only interested in types that will require an item to @@ -747,7 +747,7 @@ fn determine_rp_in_ty(ty: @ast::Ty, // locations) let sess = cx.sess; match ty.node { - ast::ty_rptr(r, _) => { + ast::ty_rptr(ref r, _) => { debug!("referenced rptr type %s", pprust::ty_to_str(ty, sess.intr())); @@ -762,7 +762,7 @@ fn determine_rp_in_ty(ty: @ast::Ty, pprust::ty_to_str(ty, sess.intr())); match f.region { Some(_) => { - if cx.region_is_relevant(f.region) { + if cx.region_is_relevant(&f.region) { let rv = cx.add_variance(rv_contravariant); cx.add_rp(cx.item_id, rv) } @@ -784,13 +784,13 @@ fn determine_rp_in_ty(ty: @ast::Ty, // then check whether it is region-parameterized and consider // that as a direct dependency. match ty.node { - ast::ty_path(path, _bounds, id) => { + ast::ty_path(ref path, _, id) => { match cx.def_map.find(&id) { Some(&ast::def_ty(did)) | Some(&ast::def_trait(did)) | Some(&ast::def_struct(did)) => { if did.crate == ast::local_crate { - if cx.region_is_relevant(path.rp) { + if cx.region_is_relevant(&path.rp) { cx.add_dep(did.node); } } else { @@ -800,7 +800,7 @@ fn determine_rp_in_ty(ty: @ast::Ty, Some(variance) => { debug!("reference to external, rp'd type %s", pprust::ty_to_str(ty, sess.intr())); - if cx.region_is_relevant(path.rp) { + if cx.region_is_relevant(&path.rp) { let rv = cx.add_variance(variance); cx.add_rp(cx.item_id, rv) } @@ -815,16 +815,16 @@ fn determine_rp_in_ty(ty: @ast::Ty, } match ty.node { - ast::ty_box(mt) | ast::ty_uniq(mt) | ast::ty_vec(mt) | - ast::ty_rptr(_, mt) | ast::ty_ptr(mt) => { + ast::ty_box(ref mt) | ast::ty_uniq(ref mt) | ast::ty_vec(ref mt) | + ast::ty_rptr(_, ref mt) | ast::ty_ptr(ref mt) => { visit_mt(mt, (cx, visitor)); } - ast::ty_path(path, _bounds, _) => { + ast::ty_path(ref path, _, _) => { // type parameters are---for now, anyway---always invariant do cx.with_ambient_variance(rv_invariant) { for path.types.iter().advance |tp| { - (visitor.visit_ty)(*tp, (cx, visitor)); + (visitor.visit_ty)(tp, (cx, visitor)); } } } @@ -837,10 +837,10 @@ fn determine_rp_in_ty(ty: @ast::Ty, // parameters are contravariant do cx.with_ambient_variance(rv_contravariant) { for decl.inputs.iter().advance |a| { - (visitor.visit_ty)(a.ty, (cx, visitor)); + (visitor.visit_ty)(&a.ty, (cx, visitor)); } } - (visitor.visit_ty)(decl.output, (cx, visitor)); + (visitor.visit_ty)(&decl.output, (cx, visitor)); } } @@ -849,7 +849,7 @@ fn determine_rp_in_ty(ty: @ast::Ty, } } - fn visit_mt(mt: ast::mt, + fn visit_mt(mt: &ast::mt, (cx, visitor): (@mut DetermineRpCtxt, visit::vt<@mut DetermineRpCtxt>)) { // mutability is invariant diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 0cbba6b1c363..041d52a69042 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -41,7 +41,6 @@ use syntax::opt_vec::OptVec; use std::str; use std::uint; -use std::vec; use std::hashmap::{HashMap, HashSet}; use std::util; @@ -511,6 +510,13 @@ pub struct NameBindings { value_def: Option, //< Meaning in value namespace. } +/// Ways in which a trait can be referenced +enum TraitReferenceType { + TraitImplementation, // impl SomeTrait for T { ... } + TraitDerivation, // trait T : SomeTrait { ... } + TraitBoundingTypeParameter, // fn f() { ... } +} + impl NameBindings { /// Creates a new module in this set of name bindings. pub fn define_module(@mut self, @@ -1227,7 +1233,7 @@ impl Resolver { visit_item(item, (new_parent, visitor)); } - item_impl(_, None, ty, ref methods) => { + item_impl(_, None, ref ty, ref methods) => { // If this implements an anonymous trait, then add all the // methods within to a new module, if the type was defined // within this module. @@ -1237,9 +1243,9 @@ impl Resolver { // the same module that declared the type. // Create the module and add all methods. - match *ty { - Ty { - node: ty_path(path, _, _), + match ty { + &Ty { + node: ty_path(ref path, _, _), _ } if path.idents.len() == 1 => { let name = path_to_ident(path); @@ -1307,7 +1313,7 @@ impl Resolver { visit_item(item, (parent, visitor)); } - item_impl(_, Some(_), _ty, ref _methods) => { + item_impl(_, Some(_), _, _) => { visit_item(item, (parent, visitor)); } @@ -1426,7 +1432,7 @@ impl Resolver { /// Constructs the reduced graph for one 'view item'. View items consist /// of imports and use directives. pub fn build_reduced_graph_for_view_item(@mut self, - view_item: @view_item, + view_item: &view_item, (parent, _): (ReducedGraphParent, vt)) { @@ -1440,7 +1446,7 @@ impl Resolver { let mut module_path = ~[]; match view_path.node { - view_path_simple(_, full_path, _) => { + view_path_simple(_, ref full_path, _) => { let path_len = full_path.idents.len(); assert!(path_len != 0); @@ -1451,8 +1457,8 @@ impl Resolver { } } - view_path_glob(module_ident_path, _) | - view_path_list(module_ident_path, _, _) => { + view_path_glob(ref module_ident_path, _) | + view_path_list(ref module_ident_path, _, _) => { for module_ident_path.idents.iter().advance |ident| { module_path.push(*ident); } @@ -1462,7 +1468,7 @@ impl Resolver { // Build up the import directives. let module_ = self.get_module_from_parent(parent); match view_path.node { - view_path_simple(binding, full_path, id) => { + view_path_simple(binding, ref full_path, id) => { let source_ident = *full_path.idents.last(); let subclass = @SingleImport(binding, source_ident); @@ -3382,7 +3388,8 @@ impl Resolver { self.session.span_err( span, - "attempted dynamic environment-capture"); + "can't capture dynamic environment in a fn item; \ + use the || { ... } closure form instead"); } else { // This was an attempt to use a type parameter outside // its scope. @@ -3404,7 +3411,8 @@ impl Resolver { self.session.span_err( span, - "attempted dynamic environment-capture"); + "can't capture dynamic environment in a fn item; \ + use the || { ... } closure form instead"); } else { // This was an attempt to use a type parameter outside // its scope. @@ -3525,8 +3533,8 @@ impl Resolver { } item_impl(ref generics, - implemented_traits, - self_type, + ref implemented_traits, + ref self_type, ref methods) => { self.resolve_implementation(item.id, generics, @@ -3553,23 +3561,7 @@ impl Resolver { // Resolve derived traits. for traits.iter().advance |trt| { - match self.resolve_path(trt.path, TypeNS, true, - visitor) { - None => - self.session.span_err(trt.path.span, - "attempt to derive a \ - nonexistent trait"), - Some(def) => { - // Write a mapping from the trait ID to the - // definition of the trait into the definition - // map. - - debug!("(resolving trait) found trait def: \ - %?", def); - - self.record_def(trt.ref_id, def); - } - } + self.resolve_trait_reference(trt, visitor, TraitDerivation); } for (*methods).iter().advance |method| { @@ -3593,10 +3585,10 @@ impl Resolver { visitor); for ty_m.decl.inputs.iter().advance |argument| { - self.resolve_type(argument.ty, visitor); + self.resolve_type(&argument.ty, visitor); } - self.resolve_type(ty_m.decl.output, visitor); + self.resolve_type(&ty_m.decl.output, visitor); } } provided(m) => { @@ -3786,12 +3778,12 @@ impl Resolver { None, visitor); - self.resolve_type(argument.ty, visitor); + self.resolve_type(&argument.ty, visitor); debug!("(resolving function) recorded argument"); } - self.resolve_type(declaration.output, visitor); + self.resolve_type(&declaration.output, visitor); } } @@ -3819,8 +3811,8 @@ impl Resolver { type_parameter_bound: &TyParamBound, visitor: ResolveVisitor) { match *type_parameter_bound { - TraitTyParamBound(tref) => { - self.resolve_trait_reference(tref, visitor) + TraitTyParamBound(ref tref) => { + self.resolve_trait_reference(tref, visitor, TraitBoundingTypeParameter) } RegionTyParamBound => {} } @@ -3828,14 +3820,23 @@ impl Resolver { pub fn resolve_trait_reference(@mut self, trait_reference: &trait_ref, - visitor: ResolveVisitor) { - match self.resolve_path(trait_reference.path, TypeNS, true, visitor) { + visitor: ResolveVisitor, + reference_type: TraitReferenceType) { + match self.resolve_path(&trait_reference.path, TypeNS, true, visitor) { None => { - self.session.span_err(trait_reference.path.span, - "attempt to implement an \ - unknown trait"); + let path_str = self.idents_to_str(trait_reference.path.idents); + + let usage_str = match reference_type { + TraitBoundingTypeParameter => "bound type parameter with", + TraitImplementation => "implement", + TraitDerivation => "derive" + }; + + let msg = fmt!("attempt to %s a nonexistent trait `%s`", usage_str, path_str); + self.session.span_err(trait_reference.path.span, msg); } Some(def) => { + debug!("(resolving trait) found trait def: %?", def); self.record_def(trait_reference.ref_id, def); } } @@ -3877,7 +3878,7 @@ impl Resolver { // Resolve fields. for fields.iter().advance |field| { - self.resolve_type(field.node.ty, visitor); + self.resolve_type(&field.node.ty, visitor); } } } @@ -3912,8 +3913,8 @@ impl Resolver { pub fn resolve_implementation(@mut self, id: node_id, generics: &Generics, - opt_trait_reference: Option<@trait_ref>, - self_type: @Ty, + opt_trait_reference: &Option, + self_type: &Ty, methods: &[@method], visitor: ResolveVisitor) { // If applicable, create a rib for the type parameters. @@ -3928,8 +3929,8 @@ impl Resolver { // Resolve the trait reference, if necessary. let original_trait_refs; match opt_trait_reference { - Some(trait_reference) => { - self.resolve_trait_reference(trait_reference, visitor); + &Some(ref trait_reference) => { + self.resolve_trait_reference(trait_reference, visitor, TraitImplementation); // Record the current set of trait references. let mut new_trait_refs = ~[]; @@ -3943,7 +3944,7 @@ impl Resolver { &mut self.current_trait_refs, Some(new_trait_refs))); } - None => { + &None => { original_trait_refs = None; } } @@ -4000,7 +4001,7 @@ impl Resolver { let mutability = if local.node.is_mutbl {Mutable} else {Immutable}; // Resolve the type. - self.resolve_type(local.node.ty, visitor); + self.resolve_type(&local.node.ty, visitor); // Resolve the initializer, if necessary. match local.node.init { @@ -4111,12 +4112,12 @@ impl Resolver { debug!("(resolving block) leaving block"); } - pub fn resolve_type(@mut self, ty: @Ty, visitor: ResolveVisitor) { + pub fn resolve_type(@mut self, ty: &Ty, visitor: ResolveVisitor) { match ty.node { // Like path expressions, the interpretation of path types depends // on whether the path has multiple elements in it or not. - ty_path(path, bounds, path_id) => { + ty_path(ref path, ref bounds, path_id) => { // This is a path in the type namespace. Walk through scopes // scopes looking for it. let mut result_def = None; @@ -4210,7 +4211,7 @@ impl Resolver { let pat_id = pattern.id; for walk_pat(pattern) |pattern| { match pattern.node { - pat_ident(binding_mode, path, _) + pat_ident(binding_mode, ref path, _) if !path.global && path.idents.len() == 1 => { // The meaning of pat_ident with no type parameters @@ -4333,11 +4334,11 @@ impl Resolver { // Check the types in the path pattern. for path.types.iter().advance |ty| { - self.resolve_type(*ty, visitor); + self.resolve_type(ty, visitor); } } - pat_ident(binding_mode, path, _) => { + pat_ident(binding_mode, ref path, _) => { // This must be an enum variant, struct, or constant. match self.resolve_path(path, ValueNS, false, visitor) { Some(def @ def_variant(*)) | @@ -4366,11 +4367,11 @@ impl Resolver { // Check the types in the path pattern. for path.types.iter().advance |ty| { - self.resolve_type(*ty, visitor); + self.resolve_type(ty, visitor); } } - pat_enum(path, _) => { + pat_enum(ref path, _) => { // This must be an enum variant, struct or const. match self.resolve_path(path, ValueNS, false, visitor) { Some(def @ def_fn(*)) | @@ -4395,7 +4396,7 @@ impl Resolver { // Check the types in the path pattern. for path.types.iter().advance |ty| { - self.resolve_type(*ty, visitor); + self.resolve_type(ty, visitor); } } @@ -4408,7 +4409,7 @@ impl Resolver { self.resolve_expr(last_expr, visitor); } - pat_struct(path, _, _) => { + pat_struct(ref path, _, _) => { match self.resolve_path(path, TypeNS, false, visitor) { Some(def_ty(class_id)) if self.structs.contains(&class_id) => { @@ -4483,14 +4484,14 @@ impl Resolver { /// If `check_ribs` is true, checks the local definitions first; i.e. /// doesn't skip straight to the containing module. pub fn resolve_path(@mut self, - path: @Path, + path: &Path, namespace: Namespace, check_ribs: bool, visitor: ResolveVisitor) -> Option { // First, resolve the types. for path.types.iter().advance |ty| { - self.resolve_type(*ty, visitor); + self.resolve_type(ty, visitor); } if path.global { @@ -4609,7 +4610,7 @@ impl Resolver { return NoNameDefinition; } - pub fn intern_module_part_of_path(@mut self, path: @Path) -> ~[ident] { + pub fn intern_module_part_of_path(@mut self, path: &Path) -> ~[ident] { let mut module_path_idents = ~[]; for path.idents.iter().enumerate().advance |(index, ident)| { if index == path.idents.len() - 1 { @@ -4623,7 +4624,7 @@ impl Resolver { } pub fn resolve_module_relative_path(@mut self, - path: @Path, + path: &Path, xray: XrayFlag, namespace: Namespace) -> Option { @@ -4689,7 +4690,7 @@ impl Resolver { /// Invariant: This must be called only during main resolution, not during /// import resolution. pub fn resolve_crate_relative_path(@mut self, - path: @Path, + path: &Path, xray: XrayFlag, namespace: Namespace) -> Option { @@ -4915,7 +4916,7 @@ impl Resolver { // The interpretation of paths depends on whether the path has // multiple elements in it or not. - expr_path(path) => { + expr_path(ref path) => { // This is a local path in the value namespace. Walk through // scopes looking for it. @@ -4984,7 +4985,7 @@ impl Resolver { visitor); } - expr_struct(path, _, _) => { + expr_struct(ref path, _, _) => { // Resolve the path to the structure it goes to. match self.resolve_path(path, TypeNS, false, visitor) { Some(def_ty(class_id)) | Some(def_struct(class_id)) @@ -5294,7 +5295,7 @@ impl Resolver { visit_crate(self.crate, ((), vt)); } - pub fn check_for_item_unused_imports(&mut self, vi: @view_item) { + pub fn check_for_item_unused_imports(&mut self, vi: &view_item) { // Ignore public import statements because there's no way to be sure // whether they're used or not. Also ignore imports with a dummy span // because this means that they were generated in some fashion by the @@ -5360,7 +5361,7 @@ impl Resolver { if idents.len() == 0 { return ~"???"; } - return self.idents_to_str(vec::reversed(idents)); + return self.idents_to_str(idents.consume_rev_iter().collect::<~[ast::ident]>()); } pub fn dump_module(@mut self, module_: @mut Module) { diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 1d69b20f5c44..b7168cbfdec5 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -385,7 +385,7 @@ pub fn expand_nested_bindings<'r>(bcx: block, do m.map |br| { match br.pats[col].node { - ast::pat_ident(_, path, Some(inner)) => { + ast::pat_ident(_, ref path, Some(inner)) => { let pats = vec::append( br.pats.slice(0u, col).to_owned(), vec::append(~[inner], @@ -441,7 +441,7 @@ pub fn enter_match<'r>(bcx: block, let this = br.pats[col]; match this.node { - ast::pat_ident(_, path, None) => { + ast::pat_ident(_, ref path, None) => { if pat_is_binding(dm, this) { let binding_info = br.data.bindings_map.get( @@ -796,7 +796,7 @@ pub fn enter_region<'r>(bcx: block, pub fn get_options(bcx: block, m: &[@Match], col: uint) -> ~[Opt] { let ccx = bcx.ccx(); fn add_to_set(tcx: ty::ctxt, set: &mut ~[Opt], val: Opt) { - if set.iter().any_(|l| opt_eq(tcx, l, &val)) {return;} + if set.iter().any(|l| opt_eq(tcx, l, &val)) {return;} set.push(val); } @@ -963,7 +963,7 @@ pub fn collect_record_or_struct_fields(bcx: block, fn extend(idents: &mut ~[ast::ident], field_pats: &[ast::field_pat]) { for field_pats.iter().advance |field_pat| { let field_ident = field_pat.ident; - if !idents.iter().any_(|x| *x == field_ident) { + if !idents.iter().any(|x| *x == field_ident) { idents.push(field_ident); } } @@ -974,7 +974,7 @@ pub fn pats_require_rooting(bcx: block, m: &[@Match], col: uint) -> bool { - do m.iter().any_ |br| { + do m.iter().any |br| { let pat_id = br.pats[col].id; let key = root_map_key {id: pat_id, derefs: 0u }; bcx.ccx().maps.root_map.contains_key(&key) @@ -1003,7 +1003,7 @@ pub fn root_pats_as_necessary(mut bcx: block, // matches may be wildcards like _ or identifiers). macro_rules! any_pat ( ($m:expr, $pattern:pat) => ( - do ($m).iter().any_ |br| { + do ($m).iter().any |br| { match br.pats[col].node { $pattern => true, _ => false @@ -1029,7 +1029,7 @@ pub fn any_tup_pat(m: &[@Match], col: uint) -> bool { } pub fn any_tuple_struct_pat(bcx: block, m: &[@Match], col: uint) -> bool { - do m.iter().any_ |br| { + do m.iter().any |br| { let pat = br.pats[col]; match pat.node { ast::pat_enum(_, Some(_)) => { @@ -1095,26 +1095,20 @@ pub fn compare_values(cx: block, match ty::get(rhs_t).sty { ty::ty_estr(ty::vstore_uniq) => { - let scratch_result = scratch_datum(cx, ty::mk_bool(), false); let scratch_lhs = alloca(cx, val_ty(lhs)); Store(cx, lhs, scratch_lhs); let scratch_rhs = alloca(cx, val_ty(rhs)); Store(cx, rhs, scratch_rhs); let did = cx.tcx().lang_items.uniq_str_eq_fn(); - let bcx = callee::trans_lang_call(cx, did, [scratch_lhs, scratch_rhs], - expr::SaveIn(scratch_result.val)); - let result = scratch_result.to_result(bcx); + let result = callee::trans_lang_call(cx, did, [scratch_lhs, scratch_rhs], None); Result { bcx: result.bcx, val: bool_to_i1(result.bcx, result.val) } } ty::ty_estr(_) => { - let scratch_result = scratch_datum(cx, ty::mk_bool(), false); let did = cx.tcx().lang_items.str_eq_fn(); - let bcx = callee::trans_lang_call(cx, did, [lhs, rhs], - expr::SaveIn(scratch_result.val)); - let result = scratch_result.to_result(bcx); + let result = callee::trans_lang_call(cx, did, [lhs, rhs], None); Result { bcx: result.bcx, val: bool_to_i1(result.bcx, result.val) @@ -1395,8 +1389,12 @@ pub fn compile_submatch(bcx: block, } if any_uniq_pat(m, col) { + let pat_ty = node_id_type(bcx, pat_id); let llbox = Load(bcx, val); - let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]); + let unboxed = match ty::get(pat_ty).sty { + ty::ty_uniq(*) if !ty::type_contents(bcx.tcx(), pat_ty).contains_managed() => llbox, + _ => GEPi(bcx, llbox, [0u, abi::box_field_body]) + }; compile_submatch(bcx, enter_uniq(bcx, dm, m, col, val), vec::append(~[unboxed], vals_left), chk); return; @@ -1868,8 +1866,12 @@ pub fn bind_irrefutable_pat(bcx: block, } } ast::pat_box(inner) | ast::pat_uniq(inner) => { + let pat_ty = node_id_type(bcx, pat.id); let llbox = Load(bcx, val); - let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]); + let unboxed = match ty::get(pat_ty).sty { + ty::ty_uniq(*) if !ty::type_contents(bcx.tcx(), pat_ty).contains_managed() => llbox, + _ => GEPi(bcx, llbox, [0u, abi::box_field_body]) + }; bcx = bind_irrefutable_pat(bcx, inner, unboxed, diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index ab813c0ffc54..dc8f6b1d05b5 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -131,13 +131,13 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr { } ty::ty_struct(def_id, ref substs) => { let fields = ty::lookup_struct_fields(cx.tcx, def_id); - let ftys = do fields.map |field| { + let mut ftys = do fields.map |field| { ty::lookup_field_type(cx.tcx, def_id, field.id, substs) }; let packed = ty::lookup_packed(cx.tcx, def_id); let dtor = ty::ty_dtor(cx.tcx, def_id).has_drop_flag(); - let ftys = - if dtor { ftys + [ty::mk_bool()] } else { ftys }; + if dtor { ftys.push(ty::mk_bool()); } + return Univariant(mk_struct(cx, ftys, packed), dtor) } ty::ty_enum(def_id, ref substs) => { @@ -147,7 +147,7 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr { mk_struct(cx, self.tys, false).size == 0 } fn find_ptr(&self) -> Option { - self.tys.iter().position_(|&ty| mono_data_classify(ty) == MonoNonNull) + self.tys.iter().position(|&ty| mono_data_classify(ty) == MonoNonNull) } } @@ -263,7 +263,7 @@ fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) -> ~[Type] { let padding = largest_size - most_aligned.size; struct_llfields(cx, most_aligned, sizing) - + [Type::array(&Type::i8(), padding)] + + &[Type::array(&Type::i8(), padding)] } } } @@ -512,7 +512,7 @@ pub fn trans_const(ccx: &mut CrateContext, r: &Repr, discr: int, let discr_ty = C_int(ccx, discr); let contents = build_const_struct(ccx, case, ~[discr_ty] + vals); - C_struct(contents + [padding(max_sz - case.size)]) + C_struct(contents + &[padding(max_sz - case.size)]) } NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => { if discr == nndiscr { diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index d598a6fbcf91..577f1c689606 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -72,6 +72,7 @@ use std::uint; use std::vec; use std::local_data; use extra::time; +use extra::sort; use syntax::ast::ident; use syntax::ast_map::{path, path_elt_to_str, path_name}; use syntax::ast_util::{local_def, path_to_ident}; @@ -141,6 +142,48 @@ fn fcx_has_nonzero_span(fcx: fn_ctxt) -> bool { } } +struct StatRecorder<'self> { + ccx: @mut CrateContext, + name: &'self str, + start: u64, + istart: uint, +} + +impl<'self> StatRecorder<'self> { + pub fn new(ccx: @mut CrateContext, + name: &'self str) -> StatRecorder<'self> { + let start = if ccx.sess.trans_stats() { + time::precise_time_ns() + } else { + 0 + }; + let istart = ccx.stats.n_llvm_insns; + StatRecorder { + ccx: ccx, + name: name, + start: start, + istart: istart, + } + } +} + +#[unsafe_destructor] +impl<'self> Drop for StatRecorder<'self> { + pub fn drop(&self) { + if self.ccx.sess.trans_stats() { + let end = time::precise_time_ns(); + let elapsed = ((end - self.start) / 1_000_000) as uint; + let iend = self.ccx.stats.n_llvm_insns; + self.ccx.stats.fn_stats.push((self.name.to_owned(), + elapsed, + iend - self.istart)); + self.ccx.stats.n_fns += 1; + // Reset LLVM insn count to avoid compound costs. + self.ccx.stats.n_llvm_insns = self.istart; + } + } +} + pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type) -> ValueRef { let llfn: ValueRef = do name.as_c_str |buf| { unsafe { @@ -246,35 +289,48 @@ pub fn malloc_raw_dyn(bcx: block, let _icx = push_ctxt("malloc_raw"); let ccx = bcx.ccx(); - let (mk_fn, langcall) = match heap { - heap_managed | heap_managed_unique => { - (ty::mk_imm_box, bcx.tcx().lang_items.malloc_fn()) - } - heap_exchange => { - (ty::mk_imm_uniq, bcx.tcx().lang_items.exchange_malloc_fn()) - } - heap_exchange_closure => { - (ty::mk_imm_uniq, bcx.tcx().lang_items.closure_exchange_malloc_fn()) - } - }; - if heap == heap_exchange { + let llty_value = type_of::type_of(ccx, t); + let llalign = llalign_of_min(ccx, llty_value); + + // Allocate space: + let r = callee::trans_lang_call( + bcx, + bcx.tcx().lang_items.exchange_malloc_fn(), + [C_i32(llalign as i32), size], + None); + rslt(r.bcx, PointerCast(r.bcx, r.val, llty_value.ptr_to())) + } else if heap == heap_exchange_vector { // Grab the TypeRef type of box_ptr_ty. - let box_ptr_ty = mk_fn(bcx.tcx(), t); + let element_type = match ty::get(t).sty { + ty::ty_unboxed_vec(e) => e, + _ => fail!("not a vector body") + }; + let box_ptr_ty = ty::mk_evec(bcx.tcx(), element_type, ty::vstore_uniq); let llty = type_of(ccx, box_ptr_ty); let llty_value = type_of::type_of(ccx, t); let llalign = llalign_of_min(ccx, llty_value); // Allocate space: - let rval = alloca(bcx, Type::i8p()); - let bcx = callee::trans_lang_call( + let r = callee::trans_lang_call( bcx, - langcall, + bcx.tcx().lang_items.vector_exchange_malloc_fn(), [C_i32(llalign as i32), size], - expr::SaveIn(rval)); - rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty)) + None); + rslt(r.bcx, PointerCast(r.bcx, r.val, llty)) } else { + // we treat ~fn, @fn and @[] as @ here, which isn't ideal + let (mk_fn, langcall) = match heap { + heap_managed | heap_managed_unique => { + (ty::mk_imm_box, bcx.tcx().lang_items.malloc_fn()) + } + heap_exchange_closure => { + (ty::mk_imm_box, bcx.tcx().lang_items.closure_exchange_malloc_fn()) + } + _ => fail!("heap_exchange/heap_exchange_vector already handled") + }; + // Grab the TypeRef type of box_ptr_ty. let box_ptr_ty = mk_fn(bcx.tcx(), t); let llty = type_of(ccx, box_ptr_ty); @@ -285,13 +341,12 @@ pub fn malloc_raw_dyn(bcx: block, // Allocate space: let tydesc = PointerCast(bcx, static_ti.tydesc, Type::i8p()); - let rval = alloca(bcx, Type::i8p()); - let bcx = callee::trans_lang_call( + let r = callee::trans_lang_call( bcx, langcall, [tydesc, size], - expr::SaveIn(rval)); - let r = rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty)); + None); + let r = rslt(r.bcx, PointerCast(r.bcx, r.val, llty)); maybe_set_managed_unique_rc(r.bcx, r.val, heap); r } @@ -316,6 +371,7 @@ pub struct MallocResult { // and pulls out the body pub fn malloc_general_dyn(bcx: block, t: ty::t, heap: heap, size: ValueRef) -> MallocResult { + assert!(heap != heap_exchange); let _icx = push_ctxt("malloc_general"); let Result {bcx: bcx, val: llbox} = malloc_raw_dyn(bcx, t, heap, size); let body = GEPi(bcx, llbox, [0u, abi::box_field_body]); @@ -323,9 +379,9 @@ pub fn malloc_general_dyn(bcx: block, t: ty::t, heap: heap, size: ValueRef) MallocResult { bcx: bcx, box: llbox, body: body } } -pub fn malloc_general(bcx: block, t: ty::t, heap: heap) - -> MallocResult { - let ty = type_of(bcx.ccx(), t); +pub fn malloc_general(bcx: block, t: ty::t, heap: heap) -> MallocResult { + let ty = type_of(bcx.ccx(), t); + assert!(heap != heap_exchange); malloc_general_dyn(bcx, t, heap, llsize_of(bcx.ccx(), ty)) } pub fn malloc_boxed(bcx: block, t: ty::t) @@ -342,6 +398,7 @@ pub fn heap_for_unique(bcx: block, t: ty::t) -> heap { } pub fn maybe_set_managed_unique_rc(bcx: block, bx: ValueRef, heap: heap) { + assert!(heap != heap_exchange); if heap == heap_managed_unique { // In cases where we are looking at a unique-typed allocation in the // managed heap (thus have refcount 1 from the managed allocator), @@ -353,11 +410,6 @@ pub fn maybe_set_managed_unique_rc(bcx: block, bx: ValueRef, heap: heap) { } } -pub fn malloc_unique(bcx: block, t: ty::t) - -> MallocResult { - malloc_general(bcx, t, heap_for_unique(bcx, t)) -} - // Type descriptor and type glue stuff pub fn get_tydesc_simple(ccx: &mut CrateContext, t: ty::t) -> ValueRef { @@ -863,10 +915,10 @@ pub fn need_invoke(bcx: block) -> bool { // Walk the scopes to look for cleanups let mut cur = bcx; + let mut cur_scope = cur.scope; loop { - match cur.kind { - block_scope(inf) => { - let inf = &mut *inf; // FIXME(#5074) workaround old borrowck + cur_scope = match cur_scope { + Some(inf) => { for inf.cleanups.iter().advance |cleanup| { match *cleanup { clean(_, cleanup_type) | clean_temp(_, _, cleanup_type) => { @@ -876,12 +928,15 @@ pub fn need_invoke(bcx: block) -> bool { } } } + inf.parent + } + None => { + cur = match cur.parent { + Some(next) => next, + None => return false + }; + cur.scope } - _ => () - } - cur = match cur.parent { - Some(next) => next, - None => return false } } } @@ -899,23 +954,21 @@ pub fn have_cached_lpad(bcx: block) -> bool { pub fn in_lpad_scope_cx(bcx: block, f: &fn(si: &mut scope_info)) { let mut bcx = bcx; + let mut cur_scope = bcx.scope; loop { - { - match bcx.kind { - block_scope(inf) => { - let len = { // FIXME(#5074) workaround old borrowck - let inf = &mut *inf; - inf.cleanups.len() - }; - if len > 0u || bcx.parent.is_none() { - f(inf); - return; - } + cur_scope = match cur_scope { + Some(inf) => { + if !inf.empty_cleanups() || (inf.parent.is_none() && bcx.parent.is_none()) { + f(inf); + return; } - _ => () + inf.parent + } + None => { + bcx = block_parent(bcx); + bcx.scope } } - bcx = block_parent(bcx); } } @@ -972,27 +1025,31 @@ pub fn get_landing_pad(bcx: block) -> BasicBlockRef { pub fn find_bcx_for_scope(bcx: block, scope_id: ast::node_id) -> block { let mut bcx_sid = bcx; + let mut cur_scope = bcx_sid.scope; loop { - bcx_sid = match bcx_sid.node_info { - Some(NodeInfo { id, _ }) if id == scope_id => { - return bcx_sid - } - - // FIXME(#6268, #6248) hacky cleanup for nested method calls - Some(NodeInfo { callee_id: Some(id), _ }) if id == scope_id => { - return bcx_sid - } - - _ => { - match bcx_sid.parent { - None => bcx.tcx().sess.bug( - fmt!("no enclosing scope with id %d", scope_id)), - Some(bcx_par) => bcx_par + cur_scope = match cur_scope { + Some(inf) => { + match inf.node_info { + Some(NodeInfo { id, _ }) if id == scope_id => { + return bcx_sid } + // FIXME(#6268, #6248) hacky cleanup for nested method calls + Some(NodeInfo { callee_id: Some(id), _ }) if id == scope_id => { + return bcx_sid + } + _ => inf.parent } } + None => { + bcx_sid = match bcx_sid.parent { + None => bcx.tcx().sess.bug(fmt!("no enclosing scope with id %d", scope_id)), + Some(bcx_par) => bcx_par + }; + bcx_sid.scope + } } } +} pub fn do_spill(bcx: block, v: ValueRef, t: ty::t) -> ValueRef { @@ -1014,13 +1071,13 @@ pub fn do_spill_noroot(cx: block, v: ValueRef) -> ValueRef { pub fn spill_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef { let _icx = push_ctxt("spill_if_immediate"); - if ty::type_is_immediate(t) { return do_spill(cx, v, t); } + if ty::type_is_immediate(cx.tcx(), t) { return do_spill(cx, v, t); } return v; } pub fn load_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef { let _icx = push_ctxt("load_if_immediate"); - if ty::type_is_immediate(t) { return Load(cx, v); } + if ty::type_is_immediate(cx.tcx(), t) { return Load(cx, v); } return v; } @@ -1145,7 +1202,7 @@ pub fn trans_stmt(cx: block, s: &ast::stmt) -> block { // You probably don't want to use this one. See the // next three functions instead. -pub fn new_block(cx: fn_ctxt, parent: Option, kind: block_kind, +pub fn new_block(cx: fn_ctxt, parent: Option, scope: Option<@mut scope_info>, is_lpad: bool, name: &str, opt_node_info: Option) -> block { @@ -1155,10 +1212,10 @@ pub fn new_block(cx: fn_ctxt, parent: Option, kind: block_kind, }; let bcx = mk_block(llbb, parent, - kind, is_lpad, opt_node_info, cx); + bcx.scope = scope; for parent.iter().advance |cx| { if cx.unreachable { Unreachable(bcx); @@ -1169,27 +1226,30 @@ pub fn new_block(cx: fn_ctxt, parent: Option, kind: block_kind, } } -pub fn simple_block_scope() -> block_kind { - block_scope(@mut scope_info { +pub fn simple_block_scope(parent: Option<@mut scope_info>, + node_info: Option) -> @mut scope_info { + @mut scope_info { + parent: parent, loop_break: None, loop_label: None, cleanups: ~[], cleanup_paths: ~[], - landing_pad: None - }) + landing_pad: None, + node_info: node_info, + } } // Use this when you're at the top block of a function or the like. pub fn top_scope_block(fcx: fn_ctxt, opt_node_info: Option) -> block { - return new_block(fcx, None, simple_block_scope(), false, + return new_block(fcx, None, Some(simple_block_scope(None, opt_node_info)), false, "function top level", opt_node_info); } pub fn scope_block(bcx: block, opt_node_info: Option, n: &str) -> block { - return new_block(bcx.fcx, Some(bcx), simple_block_scope(), bcx.is_lpad, + return new_block(bcx.fcx, Some(bcx), Some(simple_block_scope(None, opt_node_info)), bcx.is_lpad, n, opt_node_info); } @@ -1198,27 +1258,29 @@ pub fn loop_scope_block(bcx: block, loop_label: Option, n: &str, opt_node_info: Option) -> block { - return new_block(bcx.fcx, Some(bcx), block_scope(@mut scope_info { + return new_block(bcx.fcx, Some(bcx), Some(@mut scope_info { + parent: None, loop_break: Some(loop_break), loop_label: loop_label, cleanups: ~[], cleanup_paths: ~[], - landing_pad: None + landing_pad: None, + node_info: opt_node_info, }), bcx.is_lpad, n, opt_node_info); } // Use this when creating a block for the inside of a landing pad. pub fn lpad_block(bcx: block, n: &str) -> block { - new_block(bcx.fcx, Some(bcx), block_non_scope, true, n, None) + new_block(bcx.fcx, Some(bcx), None, true, n, None) } // Use this when you're making a general CFG BB within a scope. pub fn sub_block(bcx: block, n: &str) -> block { - new_block(bcx.fcx, Some(bcx), block_non_scope, bcx.is_lpad, n, None) + new_block(bcx.fcx, Some(bcx), None, bcx.is_lpad, n, None) } pub fn raw_block(fcx: fn_ctxt, is_lpad: bool, llbb: BasicBlockRef) -> block { - mk_block(llbb, None, block_non_scope, is_lpad, None, fcx) + mk_block(llbb, None, is_lpad, None, fcx) } @@ -1277,42 +1339,47 @@ pub fn cleanup_and_leave(bcx: block, (fmt!("cleanup_and_leave(%s)", cur.to_str())).to_managed()); } - match cur.kind { - block_scope(inf) if !inf.empty_cleanups() => { - let (sub_cx, dest, inf_cleanups) = { - let inf = &mut *inf; - let mut skip = 0; - let mut dest = None; - { - let r = (*inf).cleanup_paths.rev_iter().find_(|cp| cp.target == leave); - for r.iter().advance |cp| { - if cp.size == inf.cleanups.len() { - Br(bcx, cp.dest); - return; - } + let mut cur_scope = cur.scope; + loop { + cur_scope = match cur_scope { + Some (inf) if !inf.empty_cleanups() => { + let (sub_cx, dest, inf_cleanups) = { + let inf = &mut *inf; + let mut skip = 0; + let mut dest = None; + { + let r = (*inf).cleanup_paths.rev_iter().find_(|cp| cp.target == leave); + for r.iter().advance |cp| { + if cp.size == inf.cleanups.len() { + Br(bcx, cp.dest); + return; + } - skip = cp.size; - dest = Some(cp.dest); + skip = cp.size; + dest = Some(cp.dest); + } } + let sub_cx = sub_block(bcx, "cleanup"); + Br(bcx, sub_cx.llbb); + inf.cleanup_paths.push(cleanup_path { + target: leave, + size: inf.cleanups.len(), + dest: sub_cx.llbb + }); + (sub_cx, dest, inf.cleanups.tailn(skip).to_owned()) + }; + bcx = trans_block_cleanups_(sub_cx, + inf_cleanups, + is_lpad); + for dest.iter().advance |&dest| { + Br(bcx, dest); + return; } - let sub_cx = sub_block(bcx, "cleanup"); - Br(bcx, sub_cx.llbb); - inf.cleanup_paths.push(cleanup_path { - target: leave, - size: inf.cleanups.len(), - dest: sub_cx.llbb - }); - (sub_cx, dest, inf.cleanups.tailn(skip).to_owned()) - }; - bcx = trans_block_cleanups_(sub_cx, - inf_cleanups, - is_lpad); - for dest.iter().advance |&dest| { - Br(bcx, dest); - return; + inf.parent } + Some(inf) => inf.parent, + None => break } - _ => () } match upto { @@ -1353,9 +1420,12 @@ pub fn with_scope(bcx: block, bcx.to_str(), opt_node_info, name); let _indenter = indenter(); - let scope_cx = scope_block(bcx, opt_node_info, name); - Br(bcx, scope_cx.llbb); - leave_block(f(scope_cx), scope_cx) + let scope = simple_block_scope(bcx.scope, opt_node_info); + bcx.scope = Some(scope); + let ret = f(bcx); + let ret = trans_block_cleanups_(ret, /*bad*/copy scope.cleanups, false); + bcx.scope = scope.parent; + ret } pub fn with_scope_result(bcx: block, @@ -1363,10 +1433,14 @@ pub fn with_scope_result(bcx: block, name: &str, f: &fn(block) -> Result) -> Result { let _icx = push_ctxt("with_scope_result"); - let scope_cx = scope_block(bcx, opt_node_info, name); - Br(bcx, scope_cx.llbb); - let Result {bcx, val} = f(scope_cx); - rslt(leave_block(bcx, scope_cx), val) + + let scope = simple_block_scope(bcx.scope, opt_node_info); + bcx.scope = Some(scope); + let Result { bcx: out_bcx, val } = f(bcx); + let out_bcx = trans_block_cleanups_(out_bcx, /*bad*/copy scope.cleanups, false); + bcx.scope = scope.parent; + + rslt(out_bcx, val) } pub fn with_scope_datumblock(bcx: block, opt_node_info: Option, @@ -1399,7 +1473,7 @@ pub fn alloc_local(cx: block, local: &ast::local) -> block { let _icx = push_ctxt("alloc_local"); let t = node_id_type(cx, local.node.id); let simple_name = match local.node.pat.node { - ast::pat_ident(_, pth, None) => Some(path_to_ident(pth)), + ast::pat_ident(_, ref pth, None) => Some(path_to_ident(pth)), _ => None }; let val = alloc_ty(cx, t); @@ -1545,7 +1619,7 @@ pub fn mk_standard_basic_blocks(llfn: ValueRef) -> BasicBlocks { // slot where the return value of the function must go. pub fn make_return_pointer(fcx: fn_ctxt, output_type: ty::t) -> ValueRef { unsafe { - if !ty::type_is_immediate(output_type) { + if !ty::type_is_immediate(fcx.ccx.tcx, output_type) { llvm::LLVMGetParam(fcx.llfn, 0) } else { let lloutputtype = type_of::type_of(fcx.ccx, output_type); @@ -1584,7 +1658,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, ty::subst_tps(ccx.tcx, substs.tys, substs.self_ty, output_type) } }; - let is_immediate = ty::type_is_immediate(substd_output_type); + let is_immediate = ty::type_is_immediate(ccx.tcx, substd_output_type); let fcx = @mut fn_ctxt_ { llfn: llfndecl, llenv: unsafe { @@ -1690,7 +1764,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, match fcx.llself { Some(slf) => { let self_val = if slf.is_copy - && datum::appropriate_mode(slf.t).is_by_value() { + && datum::appropriate_mode(bcx.tcx(), slf.t).is_by_value() { let tmp = BitCast(bcx, slf.v, type_of(bcx.ccx(), slf.t)); let alloc = alloc_ty(bcx, slf.t); Store(bcx, tmp, alloc); @@ -1718,7 +1792,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, // This alloca should be optimized away by LLVM's mem-to-reg pass in // the event it's not truly needed. // only by value if immediate: - let llarg = if datum::appropriate_mode(arg_ty).is_by_value() { + let llarg = if datum::appropriate_mode(bcx.tcx(), arg_ty).is_by_value() { let alloc = alloc_ty(bcx, arg_ty); Store(bcx, raw_llarg, alloc); alloc @@ -1737,7 +1811,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, fcx.llargs.insert(arg_id, llarg); if fcx.ccx.sess.opts.extra_debuginfo && fcx_has_nonzero_span(fcx) { - debuginfo::create_arg(bcx, args[arg_n], args[arg_n].ty.span); + debuginfo::create_arg(bcx, &args[arg_n], args[arg_n].ty.span); } } @@ -1866,18 +1940,16 @@ pub fn trans_fn(ccx: @mut CrateContext, param_substs: Option<@param_substs>, id: ast::node_id, attrs: &[ast::attribute]) { - let do_time = ccx.sess.trans_stats(); - let start = if do_time { time::get_time() } - else { time::Timespec::new(0, 0) }; + + let the_path_str = path_str(ccx.sess, path); + let _s = StatRecorder::new(ccx, the_path_str); debug!("trans_fn(self_arg=%?, param_substs=%s)", self_arg, param_substs.repr(ccx.tcx)); let _icx = push_ctxt("trans_fn"); - ccx.stats.n_fns += 1; - let the_path_str = path_str(ccx.sess, path); let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, id)); trans_closure(ccx, - path, + copy path, decl, body, llfndecl, @@ -1893,10 +1965,6 @@ pub fn trans_fn(ccx: @mut CrateContext, } }, |_bcx| { }); - if do_time { - let end = time::get_time(); - ccx.log_fn_time(the_path_str, start, end); - } } pub fn trans_enum_variant(ccx: @mut CrateContext, @@ -1911,7 +1979,7 @@ pub fn trans_enum_variant(ccx: @mut CrateContext, let fn_args = do args.map |varg| { ast::arg { is_mutbl: false, - ty: varg.ty, + ty: copy varg.ty, pat: ast_util::ident_to_pat( ccx.tcx.sess.next_node_id(), codemap::dummy_sp(), @@ -1985,7 +2053,7 @@ pub fn trans_tuple_struct(ccx: @mut CrateContext, let fn_args = do fields.map |field| { ast::arg { is_mutbl: false, - ty: field.node.ty, + ty: copy field.node.ty, pat: ast_util::ident_to_pat(ccx.tcx.sess.next_node_id(), codemap::dummy_sp(), special_idents::arg), @@ -2961,8 +3029,14 @@ pub fn trans_crate(sess: session::Session, io::println(fmt!("n_monos: %u", ccx.stats.n_monos)); io::println(fmt!("n_inlines: %u", ccx.stats.n_inlines)); io::println(fmt!("n_closures: %u", ccx.stats.n_closures)); + io::println("fn stats:"); + do sort::quick_sort(ccx.stats.fn_stats) |&(_, _, insns_a), &(_, _, insns_b)| { + insns_a > insns_b + } + for ccx.stats.fn_stats.iter().advance |&(name, ms, insns)| { + io::println(fmt!("%u insns, %u ms, %s", insns, ms, name)); + } } - if ccx.sess.count_llvm_insns() { for ccx.stats.llvm_insns.iter().advance |(&k, &v)| { io::println(fmt!("%-7u %s", v, k)); diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index 8535c84c5cb5..b62b73423e9b 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -46,6 +46,9 @@ pub fn B(cx: block) -> BuilderRef { } pub fn count_insn(cx: block, category: &str) { + if cx.ccx().sess.trans_stats() { + cx.ccx().stats.n_llvm_insns += 1; + } do base::with_insn_ctxt |v| { let h = &mut cx.ccx().stats.llvm_insns; @@ -565,7 +568,7 @@ pub fn LoadRangeAssert(cx: block, PointerVal: ValueRef, lo: c_ulonglong, let min = llvm::LLVMConstInt(t, lo, signed); let max = llvm::LLVMConstInt(t, hi, signed); - do vec::as_imm_buf([min, max]) |ptr, len| { + do [min, max].as_imm_buf |ptr, len| { llvm::LLVMSetMetadata(value, lib::llvm::MD_range as c_uint, llvm::LLVMMDNodeInContext(cx.fcx.ccx.llcx, ptr, len as c_uint)); @@ -942,7 +945,7 @@ pub fn Call(cx: block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef { cx.val_to_str(Fn), Args.map(|arg| cx.val_to_str(*arg))); - do vec::as_imm_buf(Args) |ptr, len| { + do Args.as_imm_buf |ptr, len| { llvm::LLVMBuildCall(B(cx), Fn, ptr, len as c_uint, noname()) } } diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 41f1d0e61e53..473afda48e65 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -446,8 +446,8 @@ pub fn trans_call(in_cx: block, node_id_type(in_cx, id), |cx| trans(cx, f), args, - dest, - DontAutorefArg) + Some(dest), + DontAutorefArg).bcx } pub fn trans_method_call(in_cx: block, @@ -484,15 +484,15 @@ pub fn trans_method_call(in_cx: block, } }, args, - dest, - DontAutorefArg) + Some(dest), + DontAutorefArg).bcx } pub fn trans_lang_call(bcx: block, did: ast::def_id, args: &[ValueRef], - dest: expr::Dest) - -> block { + dest: Option) + -> Result { let fty = if did.crate == ast::local_crate { ty::node_id_to_type(bcx.ccx().tcx, did.node) } else { @@ -552,7 +552,7 @@ pub fn trans_lang_call_with_type_params(bcx: block, } Callee { bcx: callee.bcx, data: Fn(FnData { llfn: new_llval }) } }, - ArgVals(args), dest, DontAutorefArg); + ArgVals(args), Some(dest), DontAutorefArg).bcx; } pub fn body_contains_ret(body: &ast::blk) -> bool { @@ -579,10 +579,10 @@ pub fn trans_call_inner(in_cx: block, ret_ty: ty::t, get_callee: &fn(block) -> Callee, args: CallArgs, - dest: expr::Dest, + dest: Option, autoref_arg: AutorefArg) - -> block { - do base::with_scope(in_cx, call_info, "call") |cx| { + -> Result { + do base::with_scope_result(in_cx, call_info, "call") |cx| { let ret_in_loop = match args { ArgExprs(args) => { args.len() > 0u && match args.last().node { @@ -633,7 +633,7 @@ pub fn trans_call_inner(in_cx: block, let mut llargs = ~[]; - if !ty::type_is_immediate(ret_ty) { + if !ty::type_is_immediate(bcx.tcx(), ret_ty) { llargs.push(llretslot); } @@ -669,18 +669,12 @@ pub fn trans_call_inner(in_cx: block, bcx = new_bcx; match dest { - expr::Ignore => { + None => { assert!(ty::type_is_immediate(bcx.tcx(), ret_ty)) } + Some(expr::Ignore) => { // drop the value if it is not being saved. unsafe { - if llvm::LLVMIsUndef(llretslot) != lib::llvm::True { - if ty::type_is_nil(ret_ty) { - // When implementing the for-loop sugar syntax, the - // type of the for-loop is nil, but the function - // it's invoking returns a bool. This is a special - // case to ignore instead of invoking the Store - // below into a scratch pointer of a mismatched - // type. - } else if ty::type_is_immediate(ret_ty) { + if ty::type_needs_drop(bcx.tcx(), ret_ty) { + if ty::type_is_immediate(bcx.tcx(), ret_ty) { let llscratchptr = alloc_ty(bcx, ret_ty); Store(bcx, llresult, llscratchptr); bcx = glue::drop_ty(bcx, llscratchptr, ret_ty); @@ -690,11 +684,11 @@ pub fn trans_call_inner(in_cx: block, } } } - expr::SaveIn(lldest) => { + Some(expr::SaveIn(lldest)) => { // If this is an immediate, store into the result location. // (If this was not an immediate, the result will already be // directly written into the output slot.) - if ty::type_is_immediate(ret_ty) { + if ty::type_is_immediate(bcx.tcx(), ret_ty) { Store(bcx, llresult, lldest); } } @@ -717,7 +711,7 @@ pub fn trans_call_inner(in_cx: block, bcx } } - bcx + rslt(bcx, llresult) } } @@ -727,14 +721,14 @@ pub enum CallArgs<'self> { ArgVals(&'self [ValueRef]) } -pub fn trans_ret_slot(bcx: block, fn_ty: ty::t, dest: expr::Dest) +pub fn trans_ret_slot(bcx: block, fn_ty: ty::t, dest: Option) -> ValueRef { let retty = ty::ty_fn_ret(fn_ty); match dest { - expr::SaveIn(dst) => dst, - expr::Ignore => { - if ty::type_is_nil(retty) { + Some(expr::SaveIn(dst)) => dst, + _ => { + if ty::type_is_immediate(bcx.tcx(), retty) { unsafe { llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()) } @@ -898,7 +892,7 @@ pub fn trans_arg_expr(bcx: block, } ty::ByCopy => { if ty::type_needs_drop(bcx.tcx(), arg_datum.ty) || - arg_datum.appropriate_mode().is_by_ref() { + arg_datum.appropriate_mode(bcx.tcx()).is_by_ref() { debug!("by copy arg with type %s, storing to scratch", bcx.ty_to_str(arg_datum.ty)); let scratch = scratch_datum(bcx, arg_datum.ty, false); @@ -914,7 +908,7 @@ pub fn trans_arg_expr(bcx: block, scratch.add_clean(bcx); temp_cleanups.push(scratch.val); - match scratch.appropriate_mode() { + match scratch.appropriate_mode(bcx.tcx()) { ByValue => val = Load(bcx, scratch.val), ByRef(_) => val = scratch.val, } diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 3478925753e2..4c63b8dc8445 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -531,13 +531,13 @@ pub fn make_opaque_cbox_take_glue( // Allocate memory, update original ptr, and copy existing data let opaque_tydesc = PointerCast(bcx, tydesc, Type::i8p()); - let rval = alloca(bcx, Type::i8p()); - let bcx = callee::trans_lang_call( + let mut bcx = bcx; + let llresult = unpack_result!(bcx, callee::trans_lang_call( bcx, bcx.tcx().lang_items.closure_exchange_malloc_fn(), [opaque_tydesc, sz], - expr::SaveIn(rval)); - let cbox_out = PointerCast(bcx, Load(bcx, rval), llopaquecboxty); + None)); + let cbox_out = PointerCast(bcx, llresult, llopaquecboxty); call_memcpy(bcx, cbox_out, cbox_in, sz, 1); Store(bcx, cbox_out, cboxptr); diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 5b3052a1e1f4..973a124c48ad 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -34,9 +34,6 @@ use std::cast::transmute; use std::cast; use std::hashmap::{HashMap}; use std::libc::{c_uint, c_longlong, c_ulonglong}; -use std::to_bytes; -use std::str; -use std::vec::raw::to_ptr; use std::vec; use syntax::ast::ident; use syntax::ast_map::{path, path_elt}; @@ -96,8 +93,10 @@ pub struct Stats { n_monos: uint, n_inlines: uint, n_closures: uint, + n_llvm_insns: uint, + llvm_insn_ctxt: ~[~str], llvm_insns: HashMap<~str, uint>, - fn_times: ~[(~str, int)] // (ident, time) + fn_stats: ~[(~str, uint, uint)] // (ident, time-in-ms, llvm-instructions) } pub struct BuilderRef_res { @@ -275,6 +274,7 @@ pub enum heap { heap_managed, heap_managed_unique, heap_exchange, + heap_exchange_vector, heap_exchange_closure } @@ -321,7 +321,7 @@ pub fn add_clean(bcx: block, val: ValueRef, t: ty::t) { debug!("add_clean(%s, %s, %s)", bcx.to_str(), bcx.val_to_str(val), t.repr(bcx.tcx())); let cleanup_type = cleanup_type(bcx.tcx(), t); - do in_scope_cx(bcx) |scope_info| { + do in_scope_cx(bcx, None) |scope_info| { scope_info.cleanups.push(clean(|a| glue::drop_ty(a, val, t), cleanup_type)); grow_scope_clean(scope_info); } @@ -333,25 +333,36 @@ pub fn add_clean_temp_immediate(cx: block, val: ValueRef, ty: ty::t) { cx.to_str(), cx.val_to_str(val), ty.repr(cx.tcx())); let cleanup_type = cleanup_type(cx.tcx(), ty); - do in_scope_cx(cx) |scope_info| { + do in_scope_cx(cx, None) |scope_info| { scope_info.cleanups.push( clean_temp(val, |a| glue::drop_ty_immediate(a, val, ty), cleanup_type)); grow_scope_clean(scope_info); } } + pub fn add_clean_temp_mem(bcx: block, val: ValueRef, t: ty::t) { + add_clean_temp_mem_in_scope_(bcx, None, val, t); +} + +pub fn add_clean_temp_mem_in_scope(bcx: block, scope_id: ast::node_id, val: ValueRef, t: ty::t) { + add_clean_temp_mem_in_scope_(bcx, Some(scope_id), val, t); +} + +pub fn add_clean_temp_mem_in_scope_(bcx: block, scope_id: Option, + val: ValueRef, t: ty::t) { if !ty::type_needs_drop(bcx.tcx(), t) { return; } debug!("add_clean_temp_mem(%s, %s, %s)", bcx.to_str(), bcx.val_to_str(val), t.repr(bcx.tcx())); let cleanup_type = cleanup_type(bcx.tcx(), t); - do in_scope_cx(bcx) |scope_info| { + do in_scope_cx(bcx, scope_id) |scope_info| { scope_info.cleanups.push(clean_temp(val, |a| glue::drop_ty(a, val, t), cleanup_type)); grow_scope_clean(scope_info); } } pub fn add_clean_return_to_mut(bcx: block, + scope_id: ast::node_id, root_key: root_map_key, frozen_val_ref: ValueRef, bits_val_ref: ValueRef, @@ -369,7 +380,7 @@ pub fn add_clean_return_to_mut(bcx: block, bcx.to_str(), bcx.val_to_str(frozen_val_ref), bcx.val_to_str(bits_val_ref)); - do in_scope_cx(bcx) |scope_info| { + do in_scope_cx(bcx, Some(scope_id)) |scope_info| { scope_info.cleanups.push( clean_temp( frozen_val_ref, @@ -385,12 +396,12 @@ pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) { let f: @fn(block) -> block = |a| glue::trans_free(a, ptr); f } - heap_exchange | heap_exchange_closure => { + heap_exchange | heap_exchange_vector | heap_exchange_closure => { let f: @fn(block) -> block = |a| glue::trans_exchange_free(a, ptr); f } }; - do in_scope_cx(cx) |scope_info| { + do in_scope_cx(cx, None) |scope_info| { scope_info.cleanups.push(clean_temp(ptr, free_fn, normal_exit_and_unwind)); grow_scope_clean(scope_info); @@ -402,8 +413,8 @@ pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) { // this will be more involved. For now, we simply zero out the local, and the // drop glue checks whether it is zero. pub fn revoke_clean(cx: block, val: ValueRef) { - do in_scope_cx(cx) |scope_info| { - let cleanup_pos = scope_info.cleanups.iter().position_( + do in_scope_cx(cx, None) |scope_info| { + let cleanup_pos = scope_info.cleanups.iter().position( |cu| match *cu { clean_temp(v, _, _) if v == val => true, _ => false @@ -419,27 +430,14 @@ pub fn revoke_clean(cx: block, val: ValueRef) { } pub fn block_cleanups(bcx: block) -> ~[cleanup] { - match bcx.kind { - block_non_scope => ~[], - block_scope(inf) => /*bad*/copy inf.cleanups + match bcx.scope { + None => ~[], + Some(inf) => /*bad*/copy inf.cleanups } } -pub enum block_kind { - // A scope at the end of which temporary values created inside of it are - // cleaned up. May correspond to an actual block in the language, but also - // to an implicit scope, for example, calls introduce an implicit scope in - // which the arguments are evaluated and cleaned up. - block_scope(@mut scope_info), - - // A non-scope block is a basic block created as a translation artifact - // from translating code that expresses conditional logic rather than by - // explicit { ... } block structure in the source language. It's called a - // non-scope block because it doesn't introduce a new variable scope. - block_non_scope, -} - pub struct scope_info { + parent: Option<@mut scope_info>, loop_break: Option, loop_label: Option, // A list of functions that must be run at when leaving this @@ -451,6 +449,8 @@ pub struct scope_info { cleanup_paths: ~[cleanup_path], // Unwinding landing pad. Also cleared when cleanups change. landing_pad: Option, + // info about the AST node this scope originated from, if any + node_info: Option, } impl scope_info { @@ -506,8 +506,8 @@ pub struct block_ { terminated: bool, unreachable: bool, parent: Option, - // The 'kind' of basic block this is. - kind: block_kind, + // The current scope within this basic block + scope: Option<@mut scope_info>, // Is this block part of a landing pad? is_lpad: bool, // info about the AST node this block originated from, if any @@ -517,7 +517,7 @@ pub struct block_ { fcx: fn_ctxt } -pub fn block_(llbb: BasicBlockRef, parent: Option, kind: block_kind, +pub fn block_(llbb: BasicBlockRef, parent: Option, is_lpad: bool, node_info: Option, fcx: fn_ctxt) -> block_ { @@ -526,7 +526,7 @@ pub fn block_(llbb: BasicBlockRef, parent: Option, kind: block_kind, terminated: false, unreachable: false, parent: parent, - kind: kind, + scope: None, is_lpad: is_lpad, node_info: node_info, fcx: fcx @@ -535,10 +535,10 @@ pub fn block_(llbb: BasicBlockRef, parent: Option, kind: block_kind, pub type block = @mut block_; -pub fn mk_block(llbb: BasicBlockRef, parent: Option, kind: block_kind, +pub fn mk_block(llbb: BasicBlockRef, parent: Option, is_lpad: bool, node_info: Option, fcx: fn_ctxt) -> block { - @mut block_(llbb, parent, kind, is_lpad, node_info, fcx) + @mut block_(llbb, parent, is_lpad, node_info, fcx) } pub struct Result { @@ -563,19 +563,33 @@ pub fn val_ty(v: ValueRef) -> Type { } } -pub fn in_scope_cx(cx: block, f: &fn(si: &mut scope_info)) { +pub fn in_scope_cx(cx: block, scope_id: Option, f: &fn(si: &mut scope_info)) { let mut cur = cx; + let mut cur_scope = cur.scope; loop { - match cur.kind { - block_scope(inf) => { - debug!("in_scope_cx: selected cur=%s (cx=%s)", - cur.to_str(), cx.to_str()); - f(inf); - return; + cur_scope = match cur_scope { + Some(inf) => match scope_id { + Some(wanted) => match inf.node_info { + Some(NodeInfo { id: actual, _ }) if wanted == actual => { + debug!("in_scope_cx: selected cur=%s (cx=%s)", + cur.to_str(), cx.to_str()); + f(inf); + return; + }, + _ => inf.parent, + }, + None => { + debug!("in_scope_cx: selected cur=%s (cx=%s)", + cur.to_str(), cx.to_str()); + f(inf); + return; + } + }, + None => { + cur = block_parent(cur); + cur.scope } - _ => () } - cur = block_parent(cur); } } @@ -774,7 +788,7 @@ pub fn C_zero_byte_arr(size: uint) -> ValueRef { pub fn C_struct(elts: &[ValueRef]) -> ValueRef { unsafe { - do vec::as_imm_buf(elts) |ptr, len| { + do elts.as_imm_buf |ptr, len| { llvm::LLVMConstStructInContext(base::task_llcx(), ptr, len as c_uint, False) } } @@ -782,7 +796,7 @@ pub fn C_struct(elts: &[ValueRef]) -> ValueRef { pub fn C_packed_struct(elts: &[ValueRef]) -> ValueRef { unsafe { - do vec::as_imm_buf(elts) |ptr, len| { + do elts.as_imm_buf |ptr, len| { llvm::LLVMConstStructInContext(base::task_llcx(), ptr, len as c_uint, True) } } @@ -790,7 +804,7 @@ pub fn C_packed_struct(elts: &[ValueRef]) -> ValueRef { pub fn C_named_struct(T: Type, elts: &[ValueRef]) -> ValueRef { unsafe { - do vec::as_imm_buf(elts) |ptr, len| { + do elts.as_imm_buf |ptr, len| { llvm::LLVMConstNamedStruct(T.to_ref(), ptr, len as c_uint) } } @@ -826,7 +840,7 @@ pub fn get_param(fndecl: ValueRef, param: uint) -> ValueRef { pub fn const_get_elt(cx: &CrateContext, v: ValueRef, us: &[c_uint]) -> ValueRef { unsafe { - let r = do vec::as_imm_buf(us) |p, len| { + let r = do us.as_imm_buf |p, len| { llvm::LLVMConstExtractValue(v, p, len as c_uint) }; diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 9566f41a45fd..9044ef570032 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -91,7 +91,7 @@ pub fn const_vec(cx: @mut CrateContext, e: &ast::expr, es: &[@ast::expr]) let sz = llvm::LLVMConstMul(C_uint(cx, es.len()), unit_sz); let vs = es.map(|e| const_expr(cx, *e)); // If the vector contains enums, an LLVM array won't work. - let v = if vs.iter().any_(|vi| val_ty(*vi) != llunitty) { + let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) { C_struct(vs) } else { C_array(llunitty, vs) @@ -525,7 +525,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::expr) -> ValueRef { _ => cx.sess.span_bug(e.span, "bad const-slice expr") } } - ast::expr_path(pth) => { + ast::expr_path(ref pth) => { assert_eq!(pth.types.len(), 0); let tcx = cx.tcx; match tcx.def_map.find(&e.id) { diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index c2a32ae041e4..ebaa31794428 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -210,8 +210,10 @@ impl CrateContext { n_monos: 0u, n_inlines: 0u, n_closures: 0u, + n_llvm_insns: 0u, + llvm_insn_ctxt: ~[], llvm_insns: HashMap::new(), - fn_times: ~[] + fn_stats: ~[] }, upcalls: upcall::declare_upcalls(targ_cfg, llmod), tydesc_type: tydesc_type, @@ -226,12 +228,6 @@ impl CrateContext { } } } - - pub fn log_fn_time(&mut self, name: ~str, start: time::Timespec, end: time::Timespec) { - let elapsed = 1000 * ((end.sec - start.sec) as int) + - ((end.nsec as int) - (start.nsec as int)) / 1000000; - self.stats.fn_times.push((name, elapsed)); - } } #[unsafe_destructor] diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index dc88ecbe936b..8ca4253ead8b 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -26,7 +26,6 @@ use util::ppaux; use middle::trans::type_::Type; use std::str; -use std::vec; use syntax::ast; use syntax::ast::ident; use syntax::ast_map::path_mod; @@ -190,9 +189,13 @@ pub fn trans_log(log_ex: &ast::expr, let (modpath, modname) = { let path = &mut bcx.fcx.path; - let modpath = vec::append( - ~[path_mod(ccx.sess.ident_of(ccx.link_meta.name))], - path.filtered(|e| match *e { path_mod(_) => true, _ => false })); + let mut modpath = ~[path_mod(ccx.sess.ident_of(ccx.link_meta.name))]; + for path.iter().advance |e| { + match *e { + path_mod(_) => { modpath.push(*e) } + _ => {} + } + } let modname = path_str(ccx.sess, modpath); (modpath, modname) }; @@ -246,42 +249,48 @@ pub fn trans_break_cont(bcx: block, let _icx = push_ctxt("trans_break_cont"); // Locate closest loop block, outputting cleanup as we go. let mut unwind = bcx; - let mut target; + let mut cur_scope = unwind.scope; + let mut target = unwind; + let mut quit = false; loop { - match unwind.kind { - block_scope(@scope_info { - loop_break: Some(brk), - loop_label: l, - _ - }) => { - // If we're looking for a labeled loop, check the label... - target = if to_end { - brk - } else { - unwind - }; - match opt_label { - Some(desired) => match l { - Some(actual) if actual == desired => break, - // If it doesn't match the one we want, - // don't break - _ => () - }, - None => break - } - } - _ => () + cur_scope = match cur_scope { + Some(@scope_info { + loop_break: Some(brk), + loop_label: l, + parent, + _ + }) => { + // If we're looking for a labeled loop, check the label... + target = if to_end { + brk + } else { + unwind + }; + match opt_label { + Some(desired) => match l { + Some(actual) if actual == desired => break, + // If it doesn't match the one we want, + // don't break + _ => parent, + }, + None => break, + } + } + Some(inf) => inf.parent, + None => { + unwind = match unwind.parent { + Some(bcx) => bcx, + // This is a return from a loop body block + None => { + Store(bcx, C_bool(!to_end), bcx.fcx.llretptr.get()); + cleanup_and_leave(bcx, None, Some(bcx.fcx.llreturn)); + Unreachable(bcx); + return bcx; + } + }; + unwind.scope + } } - unwind = match unwind.parent { - Some(bcx) => bcx, - // This is a return from a loop body block - None => { - Store(bcx, C_bool(!to_end), bcx.fcx.llretptr.get()); - cleanup_and_leave(bcx, None, Some(bcx.fcx.llreturn)); - Unreachable(bcx); - return bcx; - } - }; } cleanup_and_Br(bcx, unwind, target.llbb); Unreachable(bcx); @@ -386,7 +395,7 @@ fn trans_fail_value(bcx: block, let V_filename = PointerCast(bcx, V_filename, Type::i8p()); let args = ~[V_str, V_filename, C_int(ccx, V_line)]; let bcx = callee::trans_lang_call( - bcx, bcx.tcx().lang_items.fail_fn(), args, expr::Ignore); + bcx, bcx.tcx().lang_items.fail_fn(), args, Some(expr::Ignore)).bcx; Unreachable(bcx); return bcx; } @@ -397,7 +406,7 @@ pub fn trans_fail_bounds_check(bcx: block, sp: span, let (filename, line) = filename_and_line_num_from_span(bcx, sp); let args = ~[filename, line, index, len]; let bcx = callee::trans_lang_call( - bcx, bcx.tcx().lang_items.fail_bounds_check_fn(), args, expr::Ignore); + bcx, bcx.tcx().lang_items.fail_bounds_check_fn(), args, Some(expr::Ignore)).bcx; Unreachable(bcx); return bcx; } diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index 0fe3dfe80c8c..e86709d72b32 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -100,6 +100,7 @@ use middle::trans::glue; use middle::trans::tvec; use middle::trans::type_of; use middle::trans::write_guard; +use middle::trans::type_::Type; use middle::ty; use util::common::indenter; use util::ppaux::ty_to_str; @@ -188,7 +189,7 @@ pub fn scratch_datum(bcx: block, ty: ty::t, zero: bool) -> Datum { Datum { val: scratch, ty: ty, mode: ByRef(RevokeClean) } } -pub fn appropriate_mode(ty: ty::t) -> DatumMode { +pub fn appropriate_mode(tcx: ty::ctxt, ty: ty::t) -> DatumMode { /*! * * Indicates the "appropriate" mode for this value, @@ -197,7 +198,7 @@ pub fn appropriate_mode(ty: ty::t) -> DatumMode { if ty::type_is_nil(ty) || ty::type_is_bot(ty) { ByValue - } else if ty::type_is_immediate(ty) { + } else if ty::type_is_immediate(tcx, ty) { ByValue } else { ByRef(RevokeClean) @@ -508,10 +509,10 @@ impl Datum { } } - pub fn appropriate_mode(&self) -> DatumMode { + pub fn appropriate_mode(&self, tcx: ty::ctxt) -> DatumMode { /*! See the `appropriate_mode()` function */ - appropriate_mode(self.ty) + appropriate_mode(tcx, self.ty) } pub fn to_appropriate_llval(&self, bcx: block) -> ValueRef { @@ -519,7 +520,7 @@ impl Datum { * * Yields an llvalue with the `appropriate_mode()`. */ - match self.appropriate_mode() { + match self.appropriate_mode(bcx.tcx()) { ByValue => self.to_value_llval(bcx), ByRef(_) => self.to_ref_llval(bcx) } @@ -530,7 +531,7 @@ impl Datum { * * Yields a datum with the `appropriate_mode()`. */ - match self.appropriate_mode() { + match self.appropriate_mode(bcx.tcx()) { ByValue => self.to_value_datum(bcx), ByRef(_) => self.to_ref_datum(bcx) } @@ -567,8 +568,14 @@ impl Datum { * This datum must represent an @T or ~T box. Returns a new * by-ref datum of type T, pointing at the contents. */ - let content_ty = match ty::get(self.ty).sty { - ty::ty_box(mt) | ty::ty_uniq(mt) => mt.ty, + let (content_ty, header) = match ty::get(self.ty).sty { + ty::ty_box(mt) => (mt.ty, true), + ty::ty_uniq(mt) => (mt.ty, false), + ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) => { + let unit_ty = ty::sequence_element_type(bcx.tcx(), self.ty); + let unboxed_vec_ty = ty::mk_mut_unboxed_vec(bcx.tcx(), unit_ty); + (unboxed_vec_ty, true) + } _ => { bcx.tcx().sess.bug(fmt!( "box_body() invoked on non-box type %s", @@ -576,9 +583,16 @@ impl Datum { } }; - let ptr = self.to_value_llval(bcx); - let body = opaque_box_body(bcx, content_ty, ptr); - Datum {val: body, ty: content_ty, mode: ByRef(ZeroMem)} + if !header && !ty::type_contents(bcx.tcx(), content_ty).contains_managed() { + let ptr = self.to_value_llval(bcx); + let ty = type_of(bcx.ccx(), content_ty); + let body = PointerCast(bcx, ptr, ty.ptr_to()); + Datum {val: body, ty: content_ty, mode: ByRef(ZeroMem)} + } else { // has a header + let ptr = self.to_value_llval(bcx); + let body = opaque_box_body(bcx, content_ty, ptr); + Datum {val: body, ty: content_ty, mode: ByRef(ZeroMem)} + } } pub fn to_rptr(&self, bcx: block) -> Datum { @@ -657,13 +671,7 @@ impl Datum { ByValue => { // Actually, this case cannot happen right // now, because enums are never immediate. - // But in principle newtype'd immediate - // values should be immediate, and in that - // case the * would be a no-op except for - // changing the type, so I am putting this - // code in place here to do the right - // thing if this change ever goes through. - assert!(ty::type_is_immediate(ty)); + assert!(ty::type_is_immediate(bcx.tcx(), ty)); (Some(Datum {ty: ty, ..*self}), bcx) } }; @@ -695,15 +703,15 @@ impl Datum { ) } ByValue => { - // Actually, this case cannot happen right now, - // because structs are never immediate. But in - // principle, newtype'd immediate values should be - // immediate, and in that case the * would be a no-op - // except for changing the type, so I am putting this - // code in place here to do the right thing if this - // change ever goes through. - assert!(ty::type_is_immediate(ty)); - (Some(Datum {ty: ty, ..*self}), bcx) + assert!(ty::type_is_immediate(bcx.tcx(), ty)); + ( + Some(Datum { + val: ExtractValue(bcx, self.val, 0), + ty: ty, + mode: ByValue + }), + bcx + ) } } } diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index ac5eb6b067c9..fc73d8053798 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -133,7 +133,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { let cx = bcx.ccx(); let ident = match local.node.pat.node { - ast::pat_ident(_, pth, _) => ast_util::path_to_ident(pth), + ast::pat_ident(_, ref pth, _) => ast_util::path_to_ident(pth), // FIXME this should be handled (#2533) _ => { bcx.sess().span_note(local.span, "debuginfo for pattern bindings NYI"); @@ -182,7 +182,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { /// /// Adds the created metadata nodes directly to the crate's IR. /// The return value should be ignored if called from outside of the debuginfo module. -pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { +pub fn create_arg(bcx: block, arg: &ast::arg, span: span) -> Option { debug!("create_arg"); if true { // XXX create_arg disabled for now because "node_id_type(bcx, arg.id)" below blows @@ -204,7 +204,7 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { let context = create_function(fcx); match arg.pat.node { - ast::pat_ident(_, path, _) => { + ast::pat_ident(_, ref path, _) => { // XXX: This is wrong; it should work for multiple bindings. let ident = path.idents.last(); let name: &str = cx.sess.str_of(*ident); @@ -259,23 +259,25 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { let fcx = &mut *fcx; let span = fcx.span.get(); - let (ident, ret_ty, id) = match cx.tcx.items.get_copy(&fcx.id) { - ast_map::node_item(item, _) => { + let fnitem = cx.tcx.items.get_copy(&fcx.id); + let (ident, ret_ty, id) = match fnitem { + ast_map::node_item(ref item, _) => { match item.node { - ast::item_fn(ref decl, _, _, _, _) => { - (item.ident, decl.output, item.id) + ast::item_fn(ast::fn_decl { output: ref ty, _}, _, _, _, _) => { + (item.ident, ty, item.id) } _ => fcx.ccx.sess.span_bug(item.span, "create_function: item bound to non-function") } } - ast_map::node_method(method, _, _) => { - (method.ident, method.decl.output, method.id) + ast_map::node_method(@ast::method { decl: ast::fn_decl { output: ref ty, _ }, + id: id, ident: ident, _}, _, _) => { + (ident, ty, id) } - ast_map::node_expr(expr) => { + ast_map::node_expr(ref expr) => { match expr.node { ast::expr_fn_block(ref decl, _) => { let name = gensym_name("fn"); - (name, decl.output, expr.id) + (name, &decl.output, expr.id) } _ => fcx.ccx.sess.span_bug(expr.span, "create_function: expected an expr_fn_block here") diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index df197ded629e..0180eeb3d220 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -150,6 +150,7 @@ use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn, use middle::ty; use util::common::indenter; use util::ppaux::Repr; +use middle::trans::machine::llsize_of; use middle::trans::type_::Type; @@ -291,7 +292,7 @@ pub fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock { debug!("add_env(closure_ty=%s)", closure_ty.repr(tcx)); let scratch = scratch_datum(bcx, closure_ty, false); let llfn = GEPi(bcx, scratch.val, [0u, abi::fn_field_code]); - assert_eq!(datum.appropriate_mode(), ByValue); + assert_eq!(datum.appropriate_mode(tcx), ByValue); Store(bcx, datum.to_appropriate_llval(bcx), llfn); let llenv = GEPi(bcx, scratch.val, [0u, abi::fn_field_box]); Store(bcx, base::null_env_ptr(bcx), llenv); @@ -464,7 +465,7 @@ fn trans_rvalue_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { expr, contents); } ast::expr_vstore(contents, ast::expr_vstore_uniq) => { - let heap = heap_for_unique(bcx, expr_ty(bcx, contents)); + let heap = tvec::heap_for_unique_vector(bcx, expr_ty(bcx, contents)); return tvec::trans_uniq_or_managed_vstore(bcx, heap, expr, contents); } @@ -1147,7 +1148,7 @@ fn trans_rec_or_struct(bcx: block, let mut need_base = vec::from_elem(field_tys.len(), true); let numbered_fields = do fields.map |field| { - let opt_pos = field_tys.iter().position_(|field_ty| field_ty.ident == field.node.ident); + let opt_pos = field_tys.iter().position(|field_ty| field_ty.ident == field.node.ident); match opt_pos { Some(i) => { need_base[i] = false; @@ -1171,7 +1172,7 @@ fn trans_rec_or_struct(bcx: block, fields: leftovers }) } None => { - if need_base.iter().any_(|b| *b) { + if need_base.iter().any(|b| *b) { tcx.sess.span_bug(expr_span, "missing fields and no base expr") } None @@ -1329,12 +1330,23 @@ fn trans_unary_datum(bcx: block, contents_ty: ty::t, heap: heap) -> DatumBlock { let _icx = push_ctxt("trans_boxed_expr"); - let base::MallocResult { bcx, box: bx, body } = - base::malloc_general(bcx, contents_ty, heap); - add_clean_free(bcx, bx, heap); - let bcx = trans_into(bcx, contents, SaveIn(body)); - revoke_clean(bcx, bx); - return immediate_rvalue_bcx(bcx, bx, box_ty); + if heap == heap_exchange { + let llty = type_of(bcx.ccx(), contents_ty); + let size = llsize_of(bcx.ccx(), llty); + let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, contents_ty, + heap_exchange, size); + add_clean_free(bcx, val, heap_exchange); + let bcx = trans_into(bcx, contents, SaveIn(val)); + revoke_clean(bcx, val); + return immediate_rvalue_bcx(bcx, val, box_ty); + } else { + let base::MallocResult { bcx, box: bx, body } = + base::malloc_general(bcx, contents_ty, heap); + add_clean_free(bcx, bx, heap); + let bcx = trans_into(bcx, contents, SaveIn(body)); + revoke_clean(bcx, bx); + return immediate_rvalue_bcx(bcx, bx, box_ty); + } } } @@ -1539,8 +1551,8 @@ fn trans_overloaded_op(bcx: block, origin) }, callee::ArgExprs(args), - dest, - DoAutorefArg) + Some(dest), + DoAutorefArg).bcx } fn int_cast(bcx: block, lldsttype: Type, llsrctype: Type, diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index c01f01db5fd1..2c505853d5eb 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -103,7 +103,7 @@ fn foreign_signature(ccx: &mut CrateContext, fn_sig: &ty::FnSig) LlvmSignature { llarg_tys: llarg_tys, llret_ty: llret_ty, - sret: !ty::type_is_immediate(fn_sig.output), + sret: !ty::type_is_immediate(ccx.tcx, fn_sig.output), } } @@ -113,7 +113,7 @@ fn shim_types(ccx: @mut CrateContext, id: ast::node_id) -> ShimTypes { _ => ccx.sess.bug("c_arg_and_ret_lltys called on non-function type") }; let llsig = foreign_signature(ccx, &fn_sig); - let bundle_ty = Type::struct_(llsig.llarg_tys + [llsig.llret_ty.ptr_to()], false); + let bundle_ty = Type::struct_(llsig.llarg_tys + &[llsig.llret_ty.ptr_to()], false); let ret_def = !ty::type_is_bot(fn_sig.output) && !ty::type_is_nil(fn_sig.output); let fn_ty = abi_info(ccx).compute_info(llsig.llarg_tys, llsig.llret_ty, ret_def); @@ -192,7 +192,7 @@ fn build_wrap_fn_(ccx: @mut CrateContext, // Patch up the return type if it's not immediate and we're returning via // the C ABI. - if needs_c_return && !ty::type_is_immediate(tys.fn_sig.output) { + if needs_c_return && !ty::type_is_immediate(ccx.tcx, tys.fn_sig.output) { let lloutputtype = type_of::type_of(fcx.ccx, tys.fn_sig.output); fcx.llretptr = Some(alloca(raw_block(fcx, false, fcx.llstaticallocas), lloutputtype)); @@ -648,7 +648,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, // intrinsics, there are no argument cleanups to // concern ourselves with. let tp_ty = substs.tys[0]; - let mode = appropriate_mode(tp_ty); + let mode = appropriate_mode(ccx.tcx, tp_ty); let src = Datum {val: get_param(decl, first_real_arg + 1u), ty: tp_ty, mode: mode}; bcx = src.move_to(bcx, DROP_EXISTING, @@ -657,7 +657,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, "move_val_init" => { // See comments for `"move_val"`. let tp_ty = substs.tys[0]; - let mode = appropriate_mode(tp_ty); + let mode = appropriate_mode(ccx.tcx, tp_ty); let src = Datum {val: get_param(decl, first_real_arg + 1u), ty: tp_ty, mode: mode}; bcx = src.move_to(bcx, INIT, get_param(decl, first_real_arg)); @@ -731,7 +731,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let lldestptr = PointerCast(bcx, lldestptr, Type::i8p()); let llsrcval = get_param(decl, first_real_arg); - let llsrcptr = if ty::type_is_immediate(in_type) { + let llsrcptr = if ty::type_is_immediate(ccx.tcx, in_type) { let llsrcptr = alloca(bcx, llintype); Store(bcx, llsrcval, llsrcptr); llsrcptr @@ -789,7 +789,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, bcx = trans_call_inner( bcx, None, fty, ty::mk_nil(), |bcx| Callee {bcx: bcx, data: Closure(datum)}, - ArgVals(arg_vals), Ignore, DontAutorefArg); + ArgVals(arg_vals), Some(Ignore), DontAutorefArg).bcx; } "morestack_addr" => { // XXX This is a hack to grab the address of this particular @@ -1221,7 +1221,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, let mut i = 0u; let n = tys.fn_sig.inputs.len(); - if !ty::type_is_immediate(tys.fn_sig.output) { + if !ty::type_is_immediate(bcx.tcx(), tys.fn_sig.output) { let llretptr = load_inbounds(bcx, llargbundle, [0u, n]); llargvals.push(llretptr); } @@ -1247,7 +1247,8 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, shim_types: &ShimTypes, llargbundle: ValueRef, llretval: ValueRef) { - if bcx.fcx.llretptr.is_some() && ty::type_is_immediate(shim_types.fn_sig.output) { + if bcx.fcx.llretptr.is_some() && + ty::type_is_immediate(bcx.tcx(), shim_types.fn_sig.output) { // Write the value into the argument bundle. let arg_count = shim_types.fn_sig.inputs.len(); let llretptr = load_inbounds(bcx, diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 68cf66789bfd..bc493bfa23ec 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -47,7 +47,7 @@ pub fn trans_free(cx: block, v: ValueRef) -> block { callee::trans_lang_call(cx, cx.tcx().lang_items.free_fn(), [PointerCast(cx, v, Type::i8p())], - expr::Ignore) + Some(expr::Ignore)).bcx } pub fn trans_exchange_free(cx: block, v: ValueRef) -> block { @@ -55,7 +55,7 @@ pub fn trans_exchange_free(cx: block, v: ValueRef) -> block { callee::trans_lang_call(cx, cx.tcx().lang_items.exchange_free_fn(), [PointerCast(cx, v, Type::i8p())], - expr::Ignore) + Some(expr::Ignore)).bcx } pub fn take_ty(cx: block, v: ValueRef, t: ty::t) -> block { @@ -386,7 +386,9 @@ pub fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) { ty::ty_uniq(*) => { uniq::make_free_glue(bcx, v, t) } - ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) | + ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) => { + tvec::make_uniq_free_glue(bcx, v, t) + } ty::ty_evec(_, ty::vstore_box) | ty::ty_estr(ty::vstore_box) => { make_free_glue(bcx, v, tvec::expand_boxed_vec_ty(bcx.tcx(), t)); @@ -738,15 +740,9 @@ pub fn make_generic_glue(ccx: @mut CrateContext, name: &str) -> ValueRef { let _icx = push_ctxt("make_generic_glue"); - if !ccx.sess.trans_stats() { - return make_generic_glue_inner(ccx, t, llfn, helper); - } - - let start = time::get_time(); - let llval = make_generic_glue_inner(ccx, t, llfn, helper); - let end = time::get_time(); - ccx.log_fn_time(fmt!("glue %s %s", name, ty_to_short_str(ccx.tcx, t)), start, end); - return llval; + let glue_name = fmt!("glue %s %s", name, ty_to_short_str(ccx.tcx, t)); + let _s = StatRecorder::new(ccx, glue_name); + make_generic_glue_inner(ccx, t, llfn, helper) } pub fn emit_tydescs(ccx: &mut CrateContext) { diff --git a/src/librustc/middle/trans/machine.rs b/src/librustc/middle/trans/machine.rs index f55523b28418..2cd313ff4315 100644 --- a/src/librustc/middle/trans/machine.rs +++ b/src/librustc/middle/trans/machine.rs @@ -14,9 +14,6 @@ use lib::llvm::{ValueRef}; use lib::llvm::False; use lib::llvm::llvm; use middle::trans::common::*; -use middle::trans::type_of; -use middle::ty; -use util::ppaux::ty_to_str; use middle::trans::type_::Type; @@ -116,42 +113,3 @@ pub fn llalign_of(cx: &CrateContext, ty: Type) -> ValueRef { llvm::LLVMAlignOf(ty.to_ref()), cx.int_type.to_ref(), False); } } - -// Computes the size of the data part of an enum. -pub fn static_size_of_enum(cx: &mut CrateContext, t: ty::t) -> uint { - if cx.enum_sizes.contains_key(&t) { - return cx.enum_sizes.get_copy(&t); - } - - debug!("static_size_of_enum %s", ty_to_str(cx.tcx, t)); - - match ty::get(t).sty { - ty::ty_enum(tid, ref substs) => { - // Compute max(variant sizes). - let mut max_size = 0; - let variants = ty::enum_variants(cx.tcx, tid); - for variants.iter().advance |variant| { - if variant.args.len() == 0 { - loop; - } - - let lltypes = variant.args.map(|&variant_arg| { - let substituted = ty::subst(cx.tcx, substs, variant_arg); - type_of::sizing_type_of(cx, substituted) - }); - - debug!("static_size_of_enum: variant %s type %s", - cx.tcx.sess.str_of(variant.name), - cx.tn.type_to_str(Type::struct_(lltypes, false))); - - let this_size = llsize_of_real(cx, Type::struct_(lltypes, false)); - if max_size < this_size { - max_size = this_size; - } - } - cx.enum_sizes.insert(t, max_size); - return max_size; - } - _ => cx.sess.bug("static_size_of_enum called on non-enum") - } -} diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 9792e623388d..14cc822b5a57 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -577,6 +577,10 @@ pub fn trans_trait_callee_from_llval(bcx: block, } ast::sty_region(*) => { match store { + ty::UniqTraitStore + if !ty::type_contents(bcx.tcx(), callee_ty).contains_managed() => { + llself = llbox; + } ty::BoxTraitStore | ty::UniqTraitStore => { llself = GEPi(bcx, llbox, [0u, abi::box_field_body]); @@ -641,16 +645,18 @@ pub fn vtable_id(ccx: @mut CrateContext, -> mono_id { match origin { &typeck::vtable_static(impl_id, ref substs, sub_vtables) => { + let psubsts = param_substs { + tys: copy *substs, + vtables: Some(sub_vtables), + self_ty: None, + self_vtable: None + }; + monomorphize::make_mono_id( ccx, impl_id, - *substs, - if sub_vtables.is_empty() { - None - } else { - Some(sub_vtables) - }, None, + &psubsts, None) } diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index ad48c30747ed..bbcf68c386de 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -50,11 +50,13 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, fn_id=%s, \ real_substs=%s, \ vtables=%s, \ + self_vtable=%s, \ impl_did_opt=%s, \ ref_id=%?)", fn_id.repr(ccx.tcx), real_substs.repr(ccx.tcx), vtables.repr(ccx.tcx), + self_vtable.repr(ccx.tcx), impl_did_opt.repr(ccx.tcx), ref_id); @@ -71,21 +73,28 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, for real_substs.tps.iter().advance |s| { assert!(!ty::type_has_params(*s)); } for substs.iter().advance |s| { assert!(!ty::type_has_params(*s)); } let param_uses = type_use::type_uses_for(ccx, fn_id, substs.len()); - let hash_id = make_mono_id(ccx, fn_id, substs, vtables, impl_did_opt, + + let psubsts = @param_substs { + tys: substs, + vtables: vtables, + self_ty: real_substs.self_ty, + self_vtable: self_vtable + }; + + let hash_id = make_mono_id(ccx, fn_id, impl_did_opt, + &*psubsts, Some(param_uses)); - if hash_id.params.iter().any_( + if hash_id.params.iter().any( |p| match *p { mono_precise(_, _) => false, _ => true }) { must_cast = true; } debug!("monomorphic_fn(\ fn_id=%s, \ - vtables=%s, \ - substs=%s, \ + psubsts=%s, \ hash_id=%?)", fn_id.repr(ccx.tcx), - vtables.repr(ccx.tcx), - substs.repr(ccx.tcx), + psubsts.repr(ccx.tcx), hash_id); match ccx.monomorphized.find(&hash_id) { @@ -142,8 +151,8 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, ast_map::node_struct_ctor(_, i, pt) => (pt, i.ident, i.span) }; - let mono_ty = ty::subst_tps(ccx.tcx, substs, - real_substs.self_ty, llitem_ty); + let mono_ty = ty::subst_tps(ccx.tcx, psubsts.tys, + psubsts.self_ty, llitem_ty); let llfty = type_of_fn_from_ty(ccx, mono_ty); ccx.stats.n_monos += 1; @@ -172,13 +181,6 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, lldecl }; - let psubsts = Some(@param_substs { - tys: substs, - vtables: vtables, - self_ty: real_substs.self_ty, - self_vtable: self_vtable - }); - let lldecl = match map_node { ast_map::node_item(i@@ast::item { node: ast::item_fn(ref decl, _, _, _, ref body), @@ -192,7 +194,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, body, d, no_self, - psubsts, + Some(psubsts), fn_id.node, []); d @@ -202,7 +204,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, } ast_map::node_foreign_item(i, _, _, _) => { let d = mk_lldecl(); - foreign::trans_intrinsic(ccx, d, i, pt, psubsts.get(), i.attrs, + foreign::trans_intrinsic(ccx, d, i, pt, psubsts, i.attrs, ref_id); d } @@ -214,7 +216,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, match v.node.kind { ast::tuple_variant_kind(ref args) => { trans_enum_variant(ccx, enum_item.id, v, /*bad*/copy *args, - this_tv.disr_val, psubsts, d); + this_tv.disr_val, Some(psubsts), d); } ast::struct_variant_kind(_) => ccx.tcx.sess.bug("can't monomorphize struct variants"), @@ -225,13 +227,13 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, // XXX: What should the self type be here? let d = mk_lldecl(); set_inline_hint_if_appr(/*bad*/copy mth.attrs, d); - meth::trans_method(ccx, pt, mth, psubsts, d); + meth::trans_method(ccx, pt, mth, Some(psubsts), d); d } ast_map::node_trait_method(@ast::provided(mth), _, pt) => { let d = mk_lldecl(); set_inline_hint_if_appr(/*bad*/copy mth.attrs, d); - meth::trans_method(ccx, /*bad*/copy *pt, mth, psubsts, d); + meth::trans_method(ccx, /*bad*/copy *pt, mth, Some(psubsts), d); d } ast_map::node_struct_ctor(struct_def, _, _) => { @@ -241,7 +243,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, /*bad*/copy struct_def.fields, struct_def.ctor_id.expect("ast-mapped tuple struct \ didn't have a ctor id"), - psubsts, + Some(psubsts), d); d } @@ -320,26 +322,36 @@ pub fn normalize_for_monomorphization(tcx: ty::ctxt, pub fn make_mono_id(ccx: @mut CrateContext, item: ast::def_id, - substs: &[ty::t], - vtables: Option, impl_did_opt: Option, + substs: ¶m_substs, param_uses: Option<@~[type_use::type_uses]>) -> mono_id { // FIXME (possibly #5801): Need a lot of type hints to get // .collect() to work. - let precise_param_ids: ~[(ty::t, Option<@~[mono_id]>)] = match vtables { + let substs_iter = substs.self_ty.iter().chain_(substs.tys.iter()); + let precise_param_ids: ~[(ty::t, Option<@~[mono_id]>)] = match substs.vtables { Some(vts) => { debug!("make_mono_id vtables=%s substs=%s", - vts.repr(ccx.tcx), substs.repr(ccx.tcx)); - vts.iter().zip(substs.iter()).transform(|(vtable, subst)| { + vts.repr(ccx.tcx), substs.tys.repr(ccx.tcx)); + let self_vtables = substs.self_vtable.map(|vtbl| @~[copy *vtbl]); + let vts_iter = self_vtables.iter().chain_(vts.iter()); + vts_iter.zip(substs_iter).transform(|(vtable, subst)| { let v = vtable.map(|vt| meth::vtable_id(ccx, vt)); (*subst, if !v.is_empty() { Some(@v) } else { None }) }).collect() } - None => substs.iter().transform(|subst| (*subst, None::<@~[mono_id]>)).collect() + None => substs_iter.transform(|subst| (*subst, None::<@~[mono_id]>)).collect() }; + + let param_ids = match param_uses { Some(ref uses) => { - precise_param_ids.iter().zip(uses.iter()).transform(|(id, uses)| { + // param_uses doesn't include a use for the self type. + // We just say it is fully used. + let self_use = + substs.self_ty.map(|_| type_use::use_repr|type_use::use_tydesc); + let uses_iter = self_use.iter().chain_(uses.iter()); + + precise_param_ids.iter().zip(uses_iter).transform(|(id, uses)| { if ccx.sess.no_monomorphic_collapse() { match copy *id { (a, b) => mono_precise(a, b) @@ -356,7 +368,7 @@ pub fn make_mono_id(ccx: @mut CrateContext, let llty = type_of::type_of(ccx, subst); let size = machine::llbitsize_of_real(ccx, llty); let align = machine::llalign_of_min(ccx, llty); - let mode = datum::appropriate_mode(subst); + let mode = datum::appropriate_mode(ccx.tcx, subst); let data_class = mono_data_classify(subst); debug!("make_mono_id: type %s -> size %u align %u mode %? class %?", diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 9e227da49f83..cc4111aa1947 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -17,7 +17,6 @@ use middle::trans::callee::{ArgVals, DontAutorefArg}; use middle::trans::callee; use middle::trans::common::*; use middle::trans::datum::*; -use middle::trans::expr::SaveIn; use middle::trans::glue; use middle::trans::machine; use middle::trans::meth; @@ -96,14 +95,13 @@ impl Reflector { ty::mk_bare_fn(tcx, copy self.visitor_methods[mth_idx].fty); let v = self.visitor_val; debug!("passing %u args:", args.len()); - let bcx = self.bcx; + let mut bcx = self.bcx; for args.iter().enumerate().advance |(i, a)| { debug!("arg %u: %s", i, bcx.val_to_str(*a)); } let bool_ty = ty::mk_bool(); - let scratch = scratch_datum(bcx, bool_ty, false); // XXX: Should not be BoxTraitStore! - let bcx = callee::trans_call_inner( + let result = unpack_result!(bcx, callee::trans_call_inner( self.bcx, None, mth_ty, bool_ty, |bcx| meth::trans_trait_callee_from_llval(bcx, mth_ty, @@ -113,8 +111,7 @@ impl Reflector { ast::sty_region( None, ast::m_imm)), - ArgVals(args), SaveIn(scratch.val), DontAutorefArg); - let result = scratch.to_value_llval(bcx); + ArgVals(args), None, DontAutorefArg)); let result = bool_to_i1(bcx, result); let next_bcx = sub_block(bcx, "next"); CondBr(bcx, result, next_bcx.llbb, self.final_bcx.llbb); @@ -194,7 +191,11 @@ impl Reflector { } ty::ty_uniq(ref mt) => { let extra = self.c_mt(mt); - self.visit("uniq", extra) + if ty::type_contents(bcx.tcx(), t).contains_managed() { + self.visit("uniq_managed", extra) + } else { + self.visit("uniq", extra) + } } ty::ty_ptr(ref mt) => { let extra = self.c_mt(mt); @@ -278,7 +279,7 @@ impl Reflector { let opaqueptrty = ty::mk_ptr(ccx.tcx, ty::mt { ty: opaquety, mutbl: ast::m_imm }); let make_get_disr = || { - let sub_path = bcx.fcx.path + [path_name(special_idents::anon)]; + let sub_path = bcx.fcx.path + &[path_name(special_idents::anon)]; let sym = mangle_internal_name_by_path_and_seq(ccx, sub_path, "get_disr"); diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 233508c5f668..41dbe320d2d1 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -33,6 +33,23 @@ use std::option::None; use syntax::ast; use syntax::codemap; +pub fn make_uniq_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t) + -> block { + let box_datum = immediate_rvalue(Load(bcx, vptrptr), box_ty); + + let not_null = IsNotNull(bcx, box_datum.val); + do with_cond(bcx, not_null) |bcx| { + let body_datum = box_datum.box_body(bcx); + let bcx = glue::drop_ty(bcx, body_datum.to_ref_llval(bcx), + body_datum.ty); + if ty::type_contents(bcx.tcx(), box_ty).contains_managed() { + glue::trans_free(bcx, box_datum.val) + } else { + glue::trans_exchange_free(bcx, box_datum.val) + } + } +} + // Boxed vector types are in some sense currently a "shorthand" for a box // containing an unboxed vector. This expands a boxed vector type into such an // expanded type. It doesn't respect mutability, but that doesn't matter at @@ -42,7 +59,7 @@ pub fn expand_boxed_vec_ty(tcx: ty::ctxt, t: ty::t) -> ty::t { let unboxed_vec_ty = ty::mk_mut_unboxed_vec(tcx, unit_ty); match ty::get(t).sty { ty::ty_estr(ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_uniq) => { - ty::mk_imm_uniq(tcx, unboxed_vec_ty) + fail!("cannot treat vectors/strings as exchange allocations yet"); } ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) => { ty::mk_imm_box(tcx, unboxed_vec_ty) @@ -95,9 +112,17 @@ pub fn alloc_raw(bcx: block, unit_ty: ty::t, return rslt(bcx, bx); } +pub fn heap_for_unique_vector(bcx: block, t: ty::t) -> heap { + if ty::type_contents(bcx.tcx(), t).contains_managed() { + heap_managed_unique + } else { + heap_exchange_vector + } +} + pub fn alloc_uniq_raw(bcx: block, unit_ty: ty::t, fill: ValueRef, alloc: ValueRef) -> Result { - alloc_raw(bcx, unit_ty, fill, alloc, base::heap_for_unique(bcx, unit_ty)) + alloc_raw(bcx, unit_ty, fill, alloc, heap_for_unique_vector(bcx, unit_ty)) } pub fn alloc_vec(bcx: block, @@ -298,7 +323,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, heap: heap, vstore_expr: @ast::e // Handle ~"". match heap { - heap_exchange => { + heap_exchange_vector => { match content_expr.node { ast::expr_lit(@codemap::spanned { node: ast::lit_str(s), _ @@ -312,7 +337,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, heap: heap, vstore_expr: @ast::e bcx, bcx.tcx().lang_items.strdup_uniq_fn(), [ llptrval, llsizeval ], - expr::SaveIn(lldestval.to_ref_llval(bcx))); + Some(expr::SaveIn(lldestval.to_ref_llval(bcx)))).bcx; return DatumBlock { bcx: bcx, datum: lldestval @@ -321,7 +346,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, heap: heap, vstore_expr: @ast::e _ => {} } } - heap_exchange_closure => fail!("vectors are not allocated with closure_exchange_alloc"), + heap_exchange | heap_exchange_closure => fail!("vectors use vector_exchange_alloc"), heap_managed | heap_managed_unique => {} } diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index e52d33fc6e9a..7878e17f7fc6 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -245,7 +245,7 @@ impl Type { } pub fn box(ctx: &CrateContext, ty: &Type) -> Type { - Type::struct_(Type::box_header_fields(ctx) + [*ty], false) + Type::struct_(Type::box_header_fields(ctx) + &[*ty], false) } pub fn opaque_box(ctx: &CrateContext) -> Type { diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 481f08ee192d..1d2048161757 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -18,8 +18,8 @@ use middle::trans::type_::Type; use syntax::ast; -pub fn arg_is_indirect(_: &CrateContext, arg_ty: &ty::t) -> bool { - !ty::type_is_immediate(*arg_ty) +pub fn arg_is_indirect(ccx: &CrateContext, arg_ty: &ty::t) -> bool { + !ty::type_is_immediate(ccx.tcx, *arg_ty) } pub fn type_of_explicit_arg(ccx: &mut CrateContext, arg_ty: &ty::t) -> Type { @@ -41,7 +41,7 @@ pub fn type_of_fn(cx: &mut CrateContext, inputs: &[ty::t], output: ty::t) -> Typ // Arg 0: Output pointer. // (if the output type is non-immediate) - let output_is_immediate = ty::type_is_immediate(output); + let output_is_immediate = ty::type_is_immediate(cx.tcx, output); let lloutputtype = type_of(cx, output); if !output_is_immediate { atys.push(lloutputtype.ptr_to()); @@ -72,29 +72,6 @@ pub fn type_of_fn_from_ty(cx: &mut CrateContext, fty: ty::t) -> Type { } } -pub fn type_of_non_gc_box(cx: &mut CrateContext, t: ty::t) -> Type { - assert!(!ty::type_needs_infer(t)); - - let t_norm = ty::normalize_ty(cx.tcx, t); - if t != t_norm { - type_of_non_gc_box(cx, t_norm) - } else { - match ty::get(t).sty { - ty::ty_box(mt) => { - let ty = type_of(cx, mt.ty); - Type::box(cx, &ty).ptr_to() - } - ty::ty_uniq(mt) => { - let ty = type_of(cx, mt.ty); - Type::unique(cx, &ty).ptr_to() - } - _ => { - cx.sess.bug("non-box in type_of_non_gc_box"); - } - } - } -} - // A "sizing type" is an LLVM type, the size and alignment of which are // guaranteed to be equivalent to what you would get out of `type_of()`. It's // useful because: @@ -104,8 +81,7 @@ pub fn type_of_non_gc_box(cx: &mut CrateContext, t: ty::t) -> Type { // // (2) It won't make any recursive calls to determine the structure of the // type behind pointers. This can help prevent infinite loops for -// recursive types. For example, `static_size_of_enum()` relies on this -// behavior. +// recursive types. For example, enum types rely on this behavior. pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> Type { match cx.llsizingtypes.find_copy(&t) { @@ -232,7 +208,11 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type { ty::ty_opaque_box => Type::opaque_box(cx).ptr_to(), ty::ty_uniq(ref mt) => { let ty = type_of(cx, mt.ty); - Type::unique(cx, &ty).ptr_to() + if ty::type_contents(cx.tcx, mt.ty).contains_managed() { + Type::unique(cx, &ty).ptr_to() + } else { + ty.ptr_to() + } } ty::ty_evec(ref mt, ty::vstore_uniq) => { let ty = type_of(cx, mt.ty); diff --git a/src/librustc/middle/trans/uniq.rs b/src/librustc/middle/trans/uniq.rs index ada85c82b304..df9e29cad7f7 100644 --- a/src/librustc/middle/trans/uniq.rs +++ b/src/librustc/middle/trans/uniq.rs @@ -9,7 +9,6 @@ // except according to those terms. -use back; use lib::llvm::ValueRef; use middle::trans::base::*; use middle::trans::build::*; @@ -18,6 +17,9 @@ use middle::trans::datum::immediate_rvalue; use middle::trans::datum; use middle::trans::glue; use middle::ty; +use middle::trans::machine::llsize_of; +use middle::trans::type_of; +use middle::trans::type_of::*; pub fn make_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t) -> block { @@ -45,12 +47,21 @@ pub fn duplicate(bcx: block, src_box: ValueRef, src_ty: ty::t) -> Result { let body_datum = src_datum.box_body(bcx); // Malloc space in exchange heap and copy src into it - let MallocResult { - bcx: bcx, - box: dst_box, - body: dst_body - } = malloc_unique(bcx, body_datum.ty); - body_datum.copy_to(bcx, datum::INIT, dst_body); + if ty::type_contents(bcx.tcx(), src_ty).contains_managed() { + let MallocResult { + bcx: bcx, + box: dst_box, + body: dst_body + } = malloc_general(bcx, body_datum.ty, heap_managed_unique); + body_datum.copy_to(bcx, datum::INIT, dst_body); - rslt(bcx, dst_box) + rslt(bcx, dst_box) + } else { + let body_datum = body_datum.to_value_datum(bcx); + let llty = type_of(bcx.ccx(), body_datum.ty); + let size = llsize_of(bcx.ccx(), llty); + let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, body_datum.ty, heap_exchange, size); + body_datum.copy_to(bcx, datum::INIT, val); + Result { bcx: bcx, val: val } + } } diff --git a/src/librustc/middle/trans/write_guard.rs b/src/librustc/middle/trans/write_guard.rs index 068ce4e2b33b..bd22e41aff8f 100644 --- a/src/librustc/middle/trans/write_guard.rs +++ b/src/librustc/middle/trans/write_guard.rs @@ -81,7 +81,7 @@ pub fn return_to_mut(mut bcx: block, filename_val, line_val ], - expr::Ignore); + Some(expr::Ignore)).bcx; } callee::trans_lang_call( @@ -93,8 +93,8 @@ pub fn return_to_mut(mut bcx: block, filename_val, line_val ], - expr::Ignore - ) + Some(expr::Ignore) + ).bcx } fn root(datum: &Datum, @@ -123,7 +123,7 @@ fn root(datum: &Datum, let scratch = scratch_datum(bcx, datum.ty, true); datum.copy_to_datum(bcx, INIT, scratch); let cleanup_bcx = find_bcx_for_scope(bcx, root_info.scope); - add_clean_temp_mem(cleanup_bcx, scratch.val, scratch.ty); + add_clean_temp_mem_in_scope(cleanup_bcx, root_info.scope, scratch.val, scratch.ty); // Now, consider also freezing it. match root_info.freeze { @@ -144,7 +144,7 @@ fn root(datum: &Datum, let box_ptr = Load(bcx, PointerCast(bcx, scratch.val, Type::i8p().ptr_to())); - bcx = callee::trans_lang_call( + let llresult = unpack_result!(bcx, callee::trans_lang_call( bcx, freeze_did, [ @@ -152,7 +152,7 @@ fn root(datum: &Datum, filename, line ], - expr::SaveIn(scratch_bits.val)); + Some(expr::SaveIn(scratch_bits.val)))); if bcx.tcx().sess.debug_borrows() { bcx = callee::trans_lang_call( @@ -160,15 +160,15 @@ fn root(datum: &Datum, bcx.tcx().lang_items.record_borrow_fn(), [ box_ptr, - Load(bcx, scratch_bits.val), + llresult, filename, line ], - expr::Ignore); + Some(expr::Ignore)).bcx; } add_clean_return_to_mut( - cleanup_bcx, root_key, scratch.val, scratch_bits.val, + cleanup_bcx, root_info.scope, root_key, scratch.val, scratch_bits.val, filename, line); } } @@ -188,5 +188,5 @@ fn perform_write_guard(datum: &Datum, bcx, bcx.tcx().lang_items.check_not_borrowed_fn(), [PointerCast(bcx, llval, Type::i8p()), filename, line], - expr::Ignore) + Some(expr::Ignore)).bcx } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index bbf548d2659a..dce899010c76 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -29,7 +29,6 @@ use util::enum_set::{EnumSet, CLike}; use std::cast; use std::cmp; use std::hashmap::{HashMap, HashSet}; -use std::iter; use std::ops; use std::ptr::to_unsafe_ptr; use std::to_bytes; @@ -1486,8 +1485,8 @@ pub fn type_needs_subst(ty: t) -> bool { } pub fn trait_ref_contains_error(tref: &ty::TraitRef) -> bool { - tref.substs.self_ty.iter().any_(|&t| type_is_error(t)) || - tref.substs.tps.iter().any_(|&t| type_is_error(t)) + tref.substs.self_ty.iter().any(|&t| type_is_error(t)) || + tref.substs.tps.iter().any(|&t| type_is_error(t)) } pub fn type_is_ty_var(ty: t) -> bool { @@ -1647,9 +1646,22 @@ pub fn type_is_scalar(ty: t) -> bool { } } -pub fn type_is_immediate(ty: t) -> bool { +fn type_is_newtype_immediate(cx: ctxt, ty: t) -> bool { + match get(ty).sty { + ty_struct(def_id, ref substs) => { + let fields = struct_fields(cx, def_id, substs); + fields.len() == 1 && + fields[0].ident == token::special_idents::unnamed_field && + type_is_immediate(cx, fields[0].mt.ty) + } + _ => false + } +} + +pub fn type_is_immediate(cx: ctxt, ty: t) -> bool { return type_is_scalar(ty) || type_is_boxed(ty) || - type_is_unique(ty) || type_is_region_ptr(ty); + type_is_unique(ty) || type_is_region_ptr(ty) || + type_is_newtype_immediate(cx, ty); } pub fn type_needs_drop(cx: ctxt, ty: t) -> bool { @@ -1752,7 +1764,7 @@ pub struct TypeContents { impl TypeContents { pub fn meets_bounds(&self, cx: ctxt, bbs: BuiltinBounds) -> bool { - iter::all(|bb| self.meets_bound(cx, bb), |f| bbs.each(f)) + bbs.iter().all(|bb| self.meets_bound(cx, bb)) } pub fn meets_bound(&self, cx: ctxt, bb: BuiltinBound) -> bool { @@ -2330,13 +2342,13 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool { ty_struct(did, ref substs) => { seen.push(did); let fields = struct_fields(cx, did, substs); - let r = fields.iter().any_(|f| type_requires(cx, seen, r_ty, f.mt.ty)); + let r = fields.iter().any(|f| type_requires(cx, seen, r_ty, f.mt.ty)); seen.pop(); r } ty_tup(ref ts) => { - ts.iter().any_(|t| type_requires(cx, seen, r_ty, *t)) + ts.iter().any(|t| type_requires(cx, seen, r_ty, *t)) } ty_enum(ref did, _) if seen.contains(did) => { @@ -2347,7 +2359,7 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool { seen.push(did); let vs = enum_variants(cx, did); let r = !vs.is_empty() && do vs.iter().all |variant| { - do variant.args.iter().any_ |aty| { + do variant.args.iter().any |aty| { let sty = subst(cx, substs, *aty); type_requires(cx, seen, r_ty, sty) } @@ -3148,7 +3160,7 @@ pub fn expr_kind(tcx: ctxt, ast::expr_cast(*) => { match tcx.node_types.find(&(expr.id as uint)) { Some(&t) => { - if ty::type_is_immediate(t) { + if ty::type_is_immediate(tcx, t) { RvalueDatumExpr } else { RvalueDpsExpr @@ -3229,7 +3241,7 @@ pub fn field_idx_strict(tcx: ty::ctxt, id: ast::ident, fields: &[field]) } pub fn method_idx(id: ast::ident, meths: &[@Method]) -> Option { - meths.iter().position_(|m| m.ident == id) + meths.iter().position(|m| m.ident == id) } /// Returns a vector containing the indices of all type parameters that appear @@ -3612,12 +3624,12 @@ pub fn impl_trait_ref(cx: ctxt, id: ast::def_id) -> Option<@TraitRef> { debug!("(impl_trait_ref) searching for trait impl %?", id); match cx.items.find(&id.node) { Some(&ast_map::node_item(@ast::item { - node: ast::item_impl(_, opt_trait, _, _), + node: ast::item_impl(_, ref opt_trait, _, _), _}, _)) => { match opt_trait { - Some(t) => Some(ty::node_id_to_trait_ref(cx, t.ref_id)), - None => None + &Some(ref t) => Some(ty::node_id_to_trait_ref(cx, t.ref_id)), + &None => None } } _ => None @@ -3816,41 +3828,62 @@ pub fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[VariantInfo] { }, _) => { let mut disr_val = -1; @enum_definition.variants.iter().transform(|variant| { + + let ctor_ty = node_id_to_type(cx, variant.node.id); + match variant.node.kind { ast::tuple_variant_kind(ref args) => { - let ctor_ty = node_id_to_type(cx, variant.node.id); - let arg_tys = { - if args.len() > 0u { - ty_fn_args(ctor_ty).map(|a| *a) - } else { + let arg_tys = if args.len() > 0u { + ty_fn_args(ctor_ty).map(|a| *a) } + else { ~[] - } - }; + }; + match variant.node.disr_expr { Some (ex) => { disr_val = match const_eval::eval_const_expr(cx, ex) { const_eval::const_int(val) => val as int, - _ => cx.sess.bug("tag_variants: bad disr expr") + _ => cx.sess.bug("enum_variants: bad disr expr") } } _ => disr_val += 1 } - @VariantInfo_{args: arg_tys, - ctor_ty: ctor_ty, - name: variant.node.name, - id: ast_util::local_def(variant.node.id), - disr_val: disr_val, - vis: variant.node.vis + @VariantInfo_{ + args: arg_tys, + ctor_ty: ctor_ty, + name: variant.node.name, + id: ast_util::local_def(variant.node.id), + disr_val: disr_val, + vis: variant.node.vis } - } - ast::struct_variant_kind(_) => { - fail!("struct variant kinds unimpl in enum_variants") + }, + ast::struct_variant_kind(struct_def) => { + let arg_tys = + // Is this check needed for structs too, or are they always guaranteed + // to have a valid constructor function? + if struct_def.fields.len() > 0 { + ty_fn_args(ctor_ty).map(|a| *a) + } else { + ~[] + }; + + assert!(variant.node.disr_expr.is_none()); + disr_val += 1; + + @VariantInfo_{ + args: arg_tys, + ctor_ty: ctor_ty, + name: variant.node.name, + id: ast_util::local_def(variant.node.id), + disr_val: disr_val, + vis: variant.node.vis + } } } }).collect() } - _ => cx.sess.bug("tag_variants: id not bound to an enum") + _ => cx.sess.bug("enum_variants: id not bound to an enum") } }; cx.enum_var_cache.insert(id, result); diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 4d2849c52105..d8185022e416 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -85,15 +85,15 @@ pub trait AstConv { pub fn get_region_reporting_err( tcx: ty::ctxt, span: span, - a_r: Option<@ast::Lifetime>, + a_r: &Option, res: Result) -> ty::Region { match res { result::Ok(r) => r, result::Err(ref e) => { let descr = match a_r { - None => ~"anonymous lifetime", - Some(a) => fmt!("lifetime %s", + &None => ~"anonymous lifetime", + &Some(ref a) => fmt!("lifetime %s", lifetime_to_str(a, tcx.sess.intr())) }; tcx.sess.span_err( @@ -109,19 +109,19 @@ pub fn ast_region_to_region( this: &AC, rscope: &RS, default_span: span, - opt_lifetime: Option<@ast::Lifetime>) -> ty::Region + opt_lifetime: &Option) -> ty::Region { let (span, res) = match opt_lifetime { - None => { + &None => { (default_span, rscope.anon_region(default_span)) } - Some(ref lifetime) if lifetime.ident == special_idents::statik => { + &Some(ref lifetime) if lifetime.ident == special_idents::statik => { (lifetime.span, Ok(ty::re_static)) } - Some(ref lifetime) if lifetime.ident == special_idents::self_ => { + &Some(ref lifetime) if lifetime.ident == special_idents::self_ => { (lifetime.span, rscope.self_region(lifetime.span)) } - Some(ref lifetime) => { + &Some(ref lifetime) => { (lifetime.span, rscope.named_region(lifetime.span, lifetime.ident)) } @@ -136,7 +136,7 @@ fn ast_path_substs( def_id: ast::def_id, decl_generics: &ty::Generics, self_ty: Option, - path: @ast::Path) -> ty::substs + path: &ast::Path) -> ty::substs { /*! * @@ -164,11 +164,11 @@ fn ast_path_substs( } (&Some(_), &None) => { let res = rscope.anon_region(path.span); - let r = get_region_reporting_err(this.tcx(), path.span, None, res); + let r = get_region_reporting_err(this.tcx(), path.span, &None, res); Some(r) } (&Some(_), &Some(_)) => { - Some(ast_region_to_region(this, rscope, path.span, path.rp)) + Some(ast_region_to_region(this, rscope, path.span, &path.rp)) } }; @@ -179,7 +179,7 @@ fn ast_path_substs( fmt!("wrong number of type arguments: expected %u but found %u", decl_generics.type_param_defs.len(), path.types.len())); } - let tps = path.types.map(|a_t| ast_ty_to_ty(this, rscope, *a_t)); + let tps = path.types.map(|a_t| ast_ty_to_ty(this, rscope, a_t)); substs {self_r:self_r, self_ty:self_ty, tps:tps} } @@ -188,7 +188,7 @@ pub fn ast_path_to_substs_and_ty( this: &AC, rscope: &RS, did: ast::def_id, - path: @ast::Path) -> ty_param_substs_and_ty + path: &ast::Path) -> ty_param_substs_and_ty { let tcx = this.tcx(); let ty::ty_param_bounds_and_ty { @@ -206,7 +206,7 @@ pub fn ast_path_to_trait_ref( rscope: &RS, trait_def_id: ast::def_id, self_ty: Option, - path: @ast::Path) -> @ty::TraitRef + path: &ast::Path) -> @ty::TraitRef { let trait_def = this.get_trait_def(trait_def_id); @@ -228,7 +228,7 @@ pub fn ast_path_to_ty( this: &AC, rscope: &RS, did: ast::def_id, - path: @ast::Path) + path: &ast::Path) -> ty_param_substs_and_ty { // Look up the polytype of the item and then substitute the provided types @@ -276,7 +276,7 @@ pub fn ast_ty_to_ty( } return ty::mk_evec(tcx, mt, vst); } - ast::ty_path(path, bounds, id) => { + ast::ty_path(ref path, ref bounds, id) => { // Note that the "bounds must be empty if path is not a trait" // restriction is enforced in the below case for ty_path, which // will run after this as long as the path isn't a trait. @@ -321,7 +321,7 @@ pub fn ast_ty_to_ty( } fn check_path_args(tcx: ty::ctxt, - path: @ast::Path, + path: &ast::Path, flags: uint) { if (flags & NO_TPS) != 0u { if path.types.len() > 0u { @@ -371,13 +371,13 @@ pub fn ast_ty_to_ty( ast::ty_ptr(ref mt) => { ty::mk_ptr(tcx, ast_mt_to_mt(this, rscope, mt)) } - ast::ty_rptr(region, ref mt) => { + ast::ty_rptr(ref region, ref mt) => { let r = ast_region_to_region(this, rscope, ast_ty.span, region); mk_pointer(this, rscope, mt, ty::vstore_slice(r), |tmt| ty::mk_rptr(tcx, r, tmt)) } ast::ty_tup(ref fields) => { - let flds = fields.map(|t| ast_ty_to_ty(this, rscope, *t)); + let flds = fields.map(|t| ast_ty_to_ty(this, rscope, t)); ty::mk_tup(tcx, flds) } ast::ty_bare_fn(ref bf) => { @@ -398,14 +398,14 @@ pub fn ast_ty_to_ty( f.purity, f.onceness, bounds, - f.region, + &f.region, &f.decl, None, &f.lifetimes, ast_ty.span); ty::mk_closure(tcx, fn_decl) } - ast::ty_path(path, bounds, id) => { + ast::ty_path(ref path, ref bounds, id) => { let a_def = match tcx.def_map.find(&id) { None => tcx.sess.span_fatal( ast_ty.span, fmt!("unbound path %s", @@ -525,13 +525,13 @@ pub fn ty_of_arg( this: &AC, rscope: &RS, - a: ast::arg, + a: &ast::arg, expected_ty: Option) -> ty::t { match a.ty.node { ast::ty_infer if expected_ty.is_some() => expected_ty.get(), ast::ty_infer => this.ty_infer(a.ty.span), - _ => ast_ty_to_ty(this, rscope, a.ty), + _ => ast_ty_to_ty(this, rscope, &a.ty), } } @@ -553,7 +553,7 @@ pub fn bound_lifetimes( let special_idents = [special_idents::statik, special_idents::self_]; let mut bound_lifetime_names = opt_vec::Empty; ast_lifetimes.map_to_vec(|ast_lifetime| { - if special_idents.iter().any_(|&i| i == ast_lifetime.ident) { + if special_idents.iter().any(|&i| i == ast_lifetime.ident) { this.tcx().sess.span_err( ast_lifetime.span, fmt!("illegal lifetime parameter name: `%s`", @@ -621,11 +621,11 @@ fn ty_of_method_or_bare_fn( transform_self_ty(this, &rb, self_info) }); - let input_tys = decl.inputs.map(|a| ty_of_arg(this, &rb, *a, None)); + let input_tys = decl.inputs.map(|a| ty_of_arg(this, &rb, a, None)); let output_ty = match decl.output.node { ast::ty_infer => this.ty_infer(decl.output.span), - _ => ast_ty_to_ty(this, &rb, decl.output) + _ => ast_ty_to_ty(this, &rb, &decl.output) }; return (opt_transformed_self_ty, @@ -647,7 +647,7 @@ fn ty_of_method_or_bare_fn( ast::sty_value => { Some(self_info.untransformed_self_ty) } - ast::sty_region(lifetime, mutability) => { + ast::sty_region(ref lifetime, mutability) => { let region = ast_region_to_region(this, rscope, self_info.explicit_self.span, @@ -677,7 +677,7 @@ pub fn ty_of_closure( purity: ast::purity, onceness: ast::Onceness, bounds: ty::BuiltinBounds, - opt_lifetime: Option<@ast::Lifetime>, + opt_lifetime: &Option, decl: &ast::fn_decl, expected_sig: Option, lifetimes: &OptVec, @@ -695,10 +695,10 @@ pub fn ty_of_closure( // resolve the function bound region in the original region // scope `rscope`, not the scope of the function parameters let bound_region = match opt_lifetime { - Some(_) => { + &Some(_) => { ast_region_to_region(this, rscope, span, opt_lifetime) } - None => { + &None => { match sigil { ast::OwnedSigil | ast::ManagedSigil => { // @fn(), ~fn() default to static as the bound @@ -724,14 +724,14 @@ pub fn ty_of_closure( // were supplied if i < e.inputs.len() {Some(e.inputs[i])} else {None} }; - ty_of_arg(this, &rb, *a, expected_arg_ty) + ty_of_arg(this, &rb, a, expected_arg_ty) }.collect(); let expected_ret_ty = expected_sig.map(|e| e.output); let output_ty = match decl.output.node { ast::ty_infer if expected_ret_ty.is_some() => expected_ret_ty.get(), ast::ty_infer => this.ty_infer(decl.output.span), - _ => ast_ty_to_ty(this, &rb, decl.output) + _ => ast_ty_to_ty(this, &rb, &decl.output) }; ty::ClosureTy { @@ -764,7 +764,7 @@ fn conv_builtin_bounds(tcx: ty::ctxt, ast_bounds: &Option { + ast::TraitTyParamBound(ref b) => { match lookup_def_tcx(tcx, b.path.span, b.ref_id) { ast::def_trait(trait_did) => { if try_add_builtin_trait(tcx, diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index 45867ae77e08..1f7946576db5 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -105,7 +105,7 @@ pub struct pat_ctxt { map: PatIdMap, } -pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: @ast::Path, +pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: &ast::Path, subpats: &Option<~[@ast::pat]>, expected: ty::t) { // Typecheck the path. @@ -271,7 +271,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: @ast::Path, /// `etc` is true if the pattern said '...' and false otherwise. pub fn check_struct_pat_fields(pcx: &pat_ctxt, span: span, - path: @ast::Path, + path: &ast::Path, fields: &[ast::field_pat], class_fields: ~[ty::field_ty], class_id: ast::def_id, @@ -322,7 +322,7 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt, } pub fn check_struct_pat(pcx: &pat_ctxt, pat_id: ast::node_id, span: span, - expected: ty::t, path: @ast::Path, + expected: ty::t, path: &ast::Path, fields: &[ast::field_pat], etc: bool, class_id: ast::def_id, substitutions: &ty::substs) { let fcx = pcx.fcx; @@ -356,7 +356,7 @@ pub fn check_struct_like_enum_variant_pat(pcx: &pat_ctxt, pat_id: ast::node_id, span: span, expected: ty::t, - path: @ast::Path, + path: &ast::Path, fields: &[ast::field_pat], etc: bool, enum_id: ast::def_id, @@ -440,7 +440,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) { demand::suptype(fcx, pat.span, expected, const_tpt.ty); fcx.write_ty(pat.id, const_tpt.ty); } - ast::pat_ident(bm, name, sub) if pat_is_binding(tcx.def_map, pat) => { + ast::pat_ident(bm, ref name, sub) if pat_is_binding(tcx.def_map, pat) => { let typ = fcx.local_ty(pat.span, pat.id); match bm { @@ -476,13 +476,13 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) { _ => () } } - ast::pat_ident(_, path, _) => { + ast::pat_ident(_, ref path, _) => { check_pat_variant(pcx, pat, path, &Some(~[]), expected); } - ast::pat_enum(path, ref subpats) => { + ast::pat_enum(ref path, ref subpats) => { check_pat_variant(pcx, pat, path, subpats, expected); } - ast::pat_struct(path, ref fields, etc) => { + ast::pat_struct(ref path, ref fields, etc) => { // Grab the class data that we care about. let structure = structure_of(fcx, pat.span, expected); let mut error_happened = false; diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index ee61399113a4..04c83f40f6cf 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -253,7 +253,7 @@ impl<'self> LookupContext<'self> { ty_enum(did, _) => { // Watch out for newtype'd enums like "enum t = @T". // See discussion in typeck::check::do_autoderef(). - if enum_dids.iter().any_(|x| x == &did) { + if enum_dids.iter().any(|x| x == &did) { return None; } enum_dids.push(did); @@ -368,7 +368,7 @@ impl<'self> LookupContext<'self> { let trait_methods = ty::trait_methods(tcx, bound_trait_ref.def_id); let pos = { - match trait_methods.iter().position_(|m| { + match trait_methods.iter().position(|m| { m.explicit_self != ast::sty_static && m.ident == self.m_name }) { @@ -412,7 +412,7 @@ impl<'self> LookupContext<'self> { let tcx = self.tcx(); let ms = ty::trait_methods(tcx, did); - let index = match ms.iter().position_(|m| m.ident == self.m_name) { + let index = match ms.iter().position(|m| m.ident == self.m_name) { Some(i) => i, None => { return; } // no method with the right name }; @@ -466,7 +466,7 @@ impl<'self> LookupContext<'self> { // First, try self methods let mut method_info: Option = None; let methods = ty::trait_methods(tcx, did); - match methods.iter().position_(|m| m.ident == self.m_name) { + match methods.iter().position(|m| m.ident == self.m_name) { Some(i) => { method_info = Some(MethodInfo { method_ty: methods[i], @@ -482,7 +482,7 @@ impl<'self> LookupContext<'self> { for ty::trait_supertraits(tcx, did).iter().advance |trait_ref| { let supertrait_methods = ty::trait_methods(tcx, trait_ref.def_id); - match supertrait_methods.iter().position_(|m| m.ident == self.m_name) { + match supertrait_methods.iter().position(|m| m.ident == self.m_name) { Some(i) => { method_info = Some(MethodInfo { method_ty: supertrait_methods[i], @@ -538,7 +538,7 @@ impl<'self> LookupContext<'self> { impl_info.methods.map(|m| m.ident).repr(self.tcx())); let idx = { - match impl_info.methods.iter().position_(|m| m.ident == self.m_name) { + match impl_info.methods.iter().position(|m| m.ident == self.m_name) { Some(idx) => idx, None => { return; } // No method with the right name. } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 00ebca5abc14..5c8ce6b2d8bb 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -463,7 +463,6 @@ pub fn check_fn(ccx: @mut CrateCtxt, } // Check the pattern. - let region = fcx.block_region(); let pcx = pat_ctxt { fcx: fcx, map: pat_id_map(tcx.def_map, input.pat), @@ -476,7 +475,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, |local, (e, v)| { let o_ty = match local.node.ty.node { ast::ty_infer => None, - _ => Some(fcx.to_ty(local.node.ty)) + _ => Some(fcx.to_ty(&local.node.ty)) }; assign(local.node.id, o_ty); debug!("Local variable %s is assigned type %s", @@ -489,7 +488,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, // Add pattern bindings. let visit_pat: @fn(@ast::pat, ((), visit::vt<()>)) = |p, (e, v)| { match p.node { - ast::pat_ident(_, path, _) + ast::pat_ident(_, ref path, _) if pat_util::pat_is_binding(fcx.ccx.tcx.def_map, p) => { assign(p.id, None); debug!("Pattern binding %s is assigned to %s", @@ -624,7 +623,7 @@ pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) { ast::item_struct(*) => { check_struct(ccx, it.id, it.span); } - ast::item_ty(t, ref generics) => { + ast::item_ty(ref t, ref generics) => { let tpt_ty = ty::node_id_to_type(ccx.tcx, it.id); check_bounds_are_used(ccx, t.span, &generics.ty_params, tpt_ty); } @@ -790,7 +789,7 @@ impl FnCtxt { self.write_ty(node_id, ty::mk_err()); } - pub fn to_ty(&self, ast_t: @ast::Ty) -> ty::t { + pub fn to_ty(&self, ast_t: &ast::Ty) -> ty::t { ast_ty_to_ty(self, self, ast_t) } @@ -1381,7 +1380,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, rcvr: @ast::expr, method_name: ast::ident, args: &[@ast::expr], - tps: &[@ast::Ty], + tps: &[ast::Ty], sugar: ast::CallSugar) { check_expr(fcx, rcvr); @@ -1390,7 +1389,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, expr.span, fcx.expr_ty(rcvr)); - let tps = tps.map(|ast_ty| fcx.to_ty(*ast_ty)); + let tps = tps.map(|ast_ty| fcx.to_ty(ast_ty)); match method::lookup(fcx, expr, rcvr, @@ -1738,7 +1737,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, purity, expected_onceness, expected_bounds, - None, + &None, decl, expected_sig, &opt_vec::Empty, @@ -1779,7 +1778,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, expr: @ast::expr, base: @ast::expr, field: ast::ident, - tys: &[@ast::Ty]) { + tys: &[ast::Ty]) { let tcx = fcx.ccx.tcx; let bot = check_expr(fcx, base); let expr_t = structurally_resolved_type(fcx, expr.span, @@ -1809,7 +1808,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, _ => () } - let tps = tys.iter().transform(|ty| fcx.to_ty(*ty)).collect::<~[ty::t]>(); + let tps : ~[ty::t] = tys.iter().transform(|ty| fcx.to_ty(ty)).collect(); match method::lookup(fcx, expr, base, @@ -2437,7 +2436,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, }; fcx.write_ty(id, oprnd_t); } - ast::expr_path(pth) => { + ast::expr_path(ref pth) => { let defn = lookup_def(fcx, pth.span, id); let tpt = ty_param_bounds_and_ty_for_def(fcx, expr.span, defn); @@ -2622,7 +2621,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_bot(id); } } - ast::expr_cast(e, t) => { + ast::expr_cast(e, ref t) => { check_expr(fcx, e); let t_1 = fcx.to_ty(t); let t_e = fcx.expr_ty(e); @@ -2775,7 +2774,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_ty(id, typ); } } - ast::expr_struct(path, ref fields, base_expr) => { + ast::expr_struct(ref path, ref fields, base_expr) => { // Resolve the path. match tcx.def_map.find(&id) { Some(&ast::def_struct(type_def_id)) => { @@ -2892,7 +2891,6 @@ pub fn check_decl_local(fcx: @mut FnCtxt, local: @ast::local) { _ => {} } - let region = tcx.region_maps.encl_region(local.node.id); let pcx = pat_ctxt { fcx: fcx, map: pat_id_map(tcx.def_map, local.node.pat), @@ -3286,7 +3284,7 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt, // Instantiates the given path, which must refer to an item with the given // number of type parameters and type. pub fn instantiate_path(fcx: @mut FnCtxt, - pth: @ast::Path, + pth: &ast::Path, tpt: ty_param_bounds_and_ty, span: span, node_id: ast::node_id) { @@ -3310,7 +3308,7 @@ pub fn instantiate_path(fcx: @mut FnCtxt, None } Some(_) => { // ...and the type is lifetime parameterized, ok. - Some(ast_region_to_region(fcx, fcx, span, pth.rp)) + Some(ast_region_to_region(fcx, fcx, span, &pth.rp)) } } } @@ -3336,7 +3334,7 @@ pub fn instantiate_path(fcx: @mut FnCtxt, (span, "not enough type parameters provided for this item"); fcx.infcx().next_ty_vars(ty_param_count) } else { - pth.types.map(|aty| fcx.to_ty(*aty)) + pth.types.map(|aty| fcx.to_ty(aty)) }; let substs = substs { self_r: self_r, self_ty: None, tps: tps }; diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 2e41649e4dbb..65b40fbd48c5 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -36,11 +36,9 @@ use middle::typeck::check::regionmanip::relate_nested_regions; use middle::typeck::infer::resolve_and_force_all_but_regions; use middle::typeck::infer::resolve_type; use middle::typeck::infer; -use util::ppaux::{note_and_explain_region, ty_to_str, - region_to_str}; +use util::ppaux::{ty_to_str, region_to_str}; use middle::pat_util; -use std::result; use std::uint; use syntax::ast::{ManagedSigil, OwnedSigil, BorrowedSigil}; use syntax::ast::{def_arg, def_binding, def_local, def_self, def_upvar}; @@ -419,8 +417,6 @@ fn constrain_callee(rcx: @mut Rcx, call_expr: @ast::expr, callee_expr: @ast::expr) { - let tcx = rcx.fcx.tcx(); - let call_region = ty::re_scope(call_expr.id); let callee_ty = rcx.resolve_node_type(callee_id); @@ -559,8 +555,6 @@ fn constrain_index(rcx: @mut Rcx, * includes the deref expr. */ - let tcx = rcx.fcx.tcx(); - debug!("constrain_index(index_expr=?, indexed_ty=%s", rcx.fcx.infcx().ty_to_str(indexed_ty)); diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index d90863344396..7cc328674143 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -67,7 +67,7 @@ impl VtableContext { } fn has_trait_bounds(type_param_defs: &[ty::TypeParameterDef]) -> bool { - type_param_defs.iter().any_( + type_param_defs.iter().any( |type_param_def| !type_param_def.bounds.trait_bounds.is_empty()) } diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 24ac63ac7b07..473d5b8e6e88 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -207,9 +207,11 @@ impl CoherenceChecker { // self.crate_context.tcx.sess.str_of(item.ident)); match item.node { - item_impl(_, opt_trait, _, _) => { - self.check_implementation(item, - opt_trait.iter().transform(|&x| x).collect()); + item_impl(_, ref opt_trait, _, _) => { + let opt_trait : ~[trait_ref] = opt_trait.iter() + .transform(|&x| x) + .collect(); + self.check_implementation(item, opt_trait); } _ => { // Nothing to do. @@ -238,7 +240,7 @@ impl CoherenceChecker { pub fn check_implementation(&self, item: @item, - associated_traits: ~[@trait_ref]) { + associated_traits: &[trait_ref]) { let tcx = self.crate_context.tcx; let self_type = ty::lookup_item_type(tcx, local_def(item.id)); @@ -636,7 +638,7 @@ impl CoherenceChecker { // Then visit the module items. visit_mod(module_, item.span, item.id, ((), visitor)); } - item_impl(_, None, ast_ty, _) => { + item_impl(_, None, ref ast_ty, _) => { if !self.ast_type_is_defined_in_local_crate(ast_ty) { // This is an error. let session = self.crate_context.tcx.sess; @@ -646,7 +648,7 @@ impl CoherenceChecker { a trait or new type instead"); } } - item_impl(_, Some(trait_ref), _, _) => { + item_impl(_, Some(ref trait_ref), _, _) => { // `for_ty` is `Type` in `impl Trait for Type` let for_ty = ty::node_id_to_type(self.crate_context.tcx, @@ -678,7 +680,7 @@ impl CoherenceChecker { }))); } - pub fn trait_ref_to_trait_def_id(&self, trait_ref: @trait_ref) -> def_id { + pub fn trait_ref_to_trait_def_id(&self, trait_ref: &trait_ref) -> def_id { let def_map = self.crate_context.tcx.def_map; let trait_def = def_map.get_copy(&trait_ref.ref_id); let trait_id = def_id_of_def(trait_def); @@ -723,7 +725,7 @@ impl CoherenceChecker { /// For coherence, when we have `impl Type`, we need to guarantee that /// `Type` is "local" to the crate. For our purposes, this means that it /// must precisely name some nominal type defined in this crate. - pub fn ast_type_is_defined_in_local_crate(&self, original_type: @ast::Ty) + pub fn ast_type_is_defined_in_local_crate(&self, original_type: &ast::Ty) -> bool { match original_type.node { ty_path(_, _, path_id) => { @@ -805,7 +807,7 @@ impl CoherenceChecker { // Check that we have implementations of every trait method for trait_refs.iter().advance |trait_ref| { let trait_did = - self.trait_ref_to_trait_def_id(*trait_ref); + self.trait_ref_to_trait_def_id(trait_ref); self.please_check_that_trait_methods_are_implemented( &mut methods, trait_did, @@ -817,7 +819,7 @@ impl CoherenceChecker { // if a method of that name is not inherent to the // impl, use the provided definition in the trait. for trait_refs.iter().advance |trait_ref| { - let trait_did = self.trait_ref_to_trait_def_id(*trait_ref); + let trait_did = self.trait_ref_to_trait_def_id(trait_ref); self.add_provided_methods_to_impl( &mut methods, &trait_did, diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index de05aca61caf..fb544335a723 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -148,7 +148,7 @@ pub fn get_enum_variant_types(ccx: &CrateCtxt, match variant.node.kind { ast::tuple_variant_kind(ref args) if args.len() > 0 => { let rs = type_rscope(region_parameterization); - let input_tys = args.map(|va| ccx.to_ty(&rs, va.ty)); + let input_tys = args.map(|va| ccx.to_ty(&rs, &va.ty)); result_ty = Some(ty::mk_ctor_fn(tcx, input_tys, enum_ty)); } @@ -378,7 +378,7 @@ pub fn ensure_supertraits(ccx: &CrateCtxt, id: ast::node_id, sp: codemap::span, rp: Option, - ast_trait_refs: &[@ast::trait_ref], + ast_trait_refs: &[ast::trait_ref], generics: &ast::Generics) { let tcx = ccx.tcx; @@ -386,12 +386,12 @@ pub fn ensure_supertraits(ccx: &CrateCtxt, let self_ty = ty::mk_self(ccx.tcx, local_def(id)); let mut ty_trait_refs: ~[@ty::TraitRef] = ~[]; - for ast_trait_refs.iter().advance |&ast_trait_ref| { + for ast_trait_refs.iter().advance |ast_trait_ref| { let trait_ref = instantiate_trait_ref(ccx, ast_trait_ref, rp, generics, self_ty); // FIXME(#5527) Could have same trait multiple times - if ty_trait_refs.iter().any_(|other_trait| other_trait.def_id == trait_ref.def_id) { + if ty_trait_refs.iter().any(|other_trait| other_trait.def_id == trait_ref.def_id) { // This means a trait inherited from the same supertrait more // than once. tcx.sess.span_err(sp, "Duplicate supertrait in trait declaration"); @@ -441,7 +441,7 @@ pub fn compare_impl_method(tcx: ty::ctxt, fmt!("method `%s` has a `%s` declaration in the impl, \ but not in the trait", tcx.sess.str_of(trait_m.ident), - explicit_self_to_str(impl_m.explicit_self, tcx.sess.intr()))); + explicit_self_to_str(&impl_m.explicit_self, tcx.sess.intr()))); return; } (_, &ast::sty_static) => { @@ -450,7 +450,7 @@ pub fn compare_impl_method(tcx: ty::ctxt, fmt!("method `%s` has a `%s` declaration in the trait, \ but not in the impl", tcx.sess.str_of(trait_m.ident), - explicit_self_to_str(trait_m.explicit_self, tcx.sess.intr()))); + explicit_self_to_str(&trait_m.explicit_self, tcx.sess.intr()))); return; } _ => { @@ -671,7 +671,7 @@ pub fn check_methods_against_trait(ccx: &CrateCtxt, impl_m.span, fmt!("method `%s` is not a member of trait `%s`", tcx.sess.str_of(impl_m.mty.ident), - path_to_str(a_trait_ty.path, tcx.sess.intr()))); + path_to_str(&a_trait_ty.path, tcx.sess.intr()))); } } } @@ -684,7 +684,7 @@ pub fn convert_field(ccx: &CrateCtxt, generics: &ast::Generics) { let region_parameterization = RegionParameterization::from_variance_and_generics(rp, generics); - let tt = ccx.to_ty(&type_rscope(region_parameterization), v.node.ty); + let tt = ccx.to_ty(&type_rscope(region_parameterization), &v.node.ty); write_ty_to_tcx(ccx.tcx, v.node.id, tt); /* add the field to the tcache */ ccx.tcx.tcache.insert(local_def(v.node.id), @@ -813,7 +813,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::item) { generics, rp); } - ast::item_impl(ref generics, opt_trait_ref, selfty, ref ms) => { + ast::item_impl(ref generics, ref opt_trait_ref, ref selfty, ref ms) => { let i_ty_generics = ty_generics(ccx, rp, generics, 0); let region_parameterization = RegionParameterization::from_variance_and_generics(rp, generics); @@ -839,7 +839,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::item) { &i_ty_generics, generics, parent_visibility); for opt_trait_ref.iter().advance |t| { - check_methods_against_trait(ccx, generics, rp, selfty, *t, cms); + check_methods_against_trait(ccx, generics, rp, selfty, t, cms); } } ast::item_trait(ref generics, ref supertraits, ref trait_methods) => { @@ -966,7 +966,7 @@ pub fn instantiate_trait_ref(ccx: &CrateCtxt, ast::def_trait(trait_did) => { let trait_ref = astconv::ast_path_to_trait_ref( - ccx, &rscope, trait_did, Some(self_ty), ast_trait_ref.path); + ccx, &rscope, trait_did, Some(self_ty), &ast_trait_ref.path); ccx.tcx.trait_refs.insert( ast_trait_ref.ref_id, trait_ref); return trait_ref; @@ -975,7 +975,7 @@ pub fn instantiate_trait_ref(ccx: &CrateCtxt, ccx.tcx.sess.span_fatal( ast_trait_ref.path.span, fmt!("%s is not a trait", - path_to_str(ast_trait_ref.path, + path_to_str(&ast_trait_ref.path, ccx.tcx.sess.intr()))); } } @@ -1031,7 +1031,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::item) } let rp = tcx.region_paramd_items.find(&it.id).map_consume(|x| *x); match it.node { - ast::item_static(t, _, _) => { + ast::item_static(ref t, _, _) => { let typ = ccx.to_ty(&empty_rscope, t); let tpt = no_params(typ); tcx.tcache.insert(local_def(it.id), tpt); @@ -1060,7 +1060,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::item) ccx.tcx.tcache.insert(local_def(it.id), tpt); return tpt; } - ast::item_ty(t, ref generics) => { + ast::item_ty(ref t, ref generics) => { match tcx.tcache.find(&local_def(it.id)) { Some(&tpt) => return tpt, None => { } @@ -1124,7 +1124,7 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt, generics, abis) } - ast::foreign_item_static(t, _) => { + ast::foreign_item_static(ref t, _) => { ty::ty_param_bounds_and_ty { generics: ty::Generics { type_param_defs: @~[], @@ -1149,7 +1149,7 @@ pub fn ty_generics(ccx: &CrateCtxt, let param_ty = ty::param_ty {idx: base_index + offset, def_id: local_def(param.id)}; let bounds = @compute_bounds(ccx, rp, generics, - param_ty, param.bounds); + param_ty, ¶m.bounds); let def = ty::TypeParameterDef { def_id: local_def(param.id), bounds: bounds @@ -1167,7 +1167,7 @@ pub fn ty_generics(ccx: &CrateCtxt, rp: Option, generics: &ast::Generics, param_ty: ty::param_ty, - ast_bounds: @OptVec) -> ty::ParamBounds + ast_bounds: &OptVec) -> ty::ParamBounds { /*! * @@ -1184,7 +1184,7 @@ pub fn ty_generics(ccx: &CrateCtxt, }; for ast_bounds.iter().advance |ast_bound| { match *ast_bound { - TraitTyParamBound(b) => { + TraitTyParamBound(ref b) => { let ty = ty::mk_param(ccx.tcx, param_ty.idx, param_ty.def_id); let trait_ref = instantiate_trait_ref(ccx, b, rp, generics, ty); if !astconv::try_add_builtin_trait( @@ -1215,8 +1215,8 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt, let ty_generics = ty_generics(ccx, None, ast_generics, 0); let region_param_names = RegionParamNames::from_generics(ast_generics); let rb = in_binding_rscope(&empty_rscope, region_param_names); - let input_tys = decl.inputs.map(|a| ty_of_arg(ccx, &rb, *a, None) ); - let output_ty = ast_ty_to_ty(ccx, &rb, decl.output); + let input_tys = decl.inputs.map(|a| ty_of_arg(ccx, &rb, a, None) ); + let output_ty = ast_ty_to_ty(ccx, &rb, &decl.output); let t_fn = ty::mk_bare_fn( ccx.tcx, diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index f03f01732291..ee90d9661c37 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -65,7 +65,7 @@ use middle::typeck::infer::sub::Sub; use middle::typeck::infer::to_str::InferStr; use middle::typeck::infer::unify::{InferCtxtMethods}; use middle::typeck::infer::{InferCtxt, cres, ures}; -use middle::typeck::infer::{TypeOrigin, TypeTrace}; +use middle::typeck::infer::{TypeTrace}; use util::common::indent; use std::result::{iter_vec2, map_vec2}; @@ -73,7 +73,6 @@ use std::vec; use syntax::ast::{Onceness, purity}; use syntax::ast; use syntax::opt_vec; -use syntax::codemap::span; use syntax::abi::AbiSet; pub trait Combine { diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs index e533f019b469..928f33803dd8 100644 --- a/src/librustc/middle/typeck/infer/error_reporting.rs +++ b/src/librustc/middle/typeck/infer/error_reporting.rs @@ -59,23 +59,18 @@ time of error detection. */ -use std::prelude::*; use middle::ty; use middle::ty::Region; use middle::typeck::infer; use middle::typeck::infer::InferCtxt; use middle::typeck::infer::TypeTrace; -use middle::typeck::infer::TypeOrigin; use middle::typeck::infer::SubregionOrigin; use middle::typeck::infer::RegionVariableOrigin; -use middle::typeck::infer::Types; -use middle::typeck::infer::TraitRefs; use middle::typeck::infer::ValuePairs; use middle::typeck::infer::region_inference::RegionResolutionError; use middle::typeck::infer::region_inference::ConcreteFailure; use middle::typeck::infer::region_inference::SubSupConflict; use middle::typeck::infer::region_inference::SupSupConflict; -use syntax::opt_vec; use syntax::opt_vec::OptVec; use util::ppaux::UserString; use util::ppaux::note_and_explain_region; @@ -362,7 +357,7 @@ impl ErrorReporting for InferCtxt { sup, ""); } - infer::ReferenceOutlivesReferent(ty, span) => { + infer::ReferenceOutlivesReferent(ty, _) => { self.tcx.sess.span_err( origin.span(), fmt!("in type `%s`, pointer has a longer lifetime than \ diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index fefbf2336c29..32f3e8fea3a8 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -26,8 +26,7 @@ use syntax::ast::{Many, Once, extern_fn, impure_fn, m_const, m_imm, m_mutbl}; use syntax::ast::{unsafe_fn}; use syntax::ast::{Onceness, purity}; use syntax::abi::AbiSet; -use syntax::codemap::span; -use util::common::{indent, indenter}; +use util::common::{indenter}; use util::ppaux::mt_to_str; use extra::list; diff --git a/src/librustc/middle/typeck/infer/lattice.rs b/src/librustc/middle/typeck/infer/lattice.rs index b1a6aefd1794..90a316c78f96 100644 --- a/src/librustc/middle/typeck/infer/lattice.rs +++ b/src/librustc/middle/typeck/infer/lattice.rs @@ -540,7 +540,7 @@ pub fn var_ids(this: &T, isr: isr_alist) -> ~[RegionVid] { pub fn is_var_in_set(new_vars: &[RegionVid], r: ty::Region) -> bool { match r { - ty::re_infer(ty::ReVar(ref v)) => new_vars.iter().any_(|x| x == v), + ty::re_infer(ty::ReVar(ref v)) => new_vars.iter().any(|x| x == v), _ => false } } diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index efb1dc200b52..96d18976358e 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -21,7 +21,6 @@ use middle::typeck::infer::{cres, InferCtxt}; use middle::typeck::infer::fold_regions_in_sig; use middle::typeck::infer::{TypeTrace, Subtype}; use middle::typeck::isr_alist; -use util::common::indent; use util::ppaux::mt_to_str; use extra::list; @@ -30,7 +29,6 @@ use syntax::ast; use syntax::ast::{Many, Once, extern_fn, m_const, impure_fn}; use syntax::ast::{unsafe_fn}; use syntax::ast::{Onceness, purity}; -use syntax::codemap::span; pub struct Lub(CombineFields); // least-upper-bound: common supertype @@ -186,7 +184,7 @@ impl Combine for Lub { // with. for list::each(a_isr) |pair| { let (a_br, a_r) = *pair; - if tainted.iter().any_(|x| x == &a_r) { + if tainted.iter().any(|x| x == &a_r) { debug!("generalize_region(r0=%?): \ replacing with %?, tainted=%?", r0, a_br, tainted); diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index 3360edc6a467..d0a778139dbd 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -328,7 +328,7 @@ pub fn can_mk_subty(cx: @mut InferCtxt, a: ty::t, b: ty::t) -> ures { } pub fn mk_subr(cx: @mut InferCtxt, - a_is_expected: bool, + _a_is_expected: bool, origin: SubregionOrigin, a: ty::Region, b: ty::Region) { diff --git a/src/librustc/middle/typeck/infer/region_inference/mod.rs b/src/librustc/middle/typeck/infer/region_inference/mod.rs index 96cb5d3c747c..50290ba752e7 100644 --- a/src/librustc/middle/typeck/infer/region_inference/mod.rs +++ b/src/librustc/middle/typeck/infer/region_inference/mod.rs @@ -19,13 +19,12 @@ use middle::typeck::infer::cres; use middle::typeck::infer::{RegionVariableOrigin, SubregionOrigin}; use middle::typeck::infer; use util::common::indenter; -use util::ppaux::{note_and_explain_region, Repr, UserString}; +use util::ppaux::{Repr}; use std::cell::Cell; use std::hashmap::{HashMap, HashSet}; use std::uint; use std::vec; -use syntax::codemap::span; use syntax::ast; use syntax::opt_vec; use syntax::opt_vec::OptVec; @@ -455,7 +454,7 @@ impl RegionVarBindings { { let mut result_set = result_set; if r == r1 { // Clearly, this is potentially inefficient. - if !result_set.iter().any_(|x| *x == r2) { + if !result_set.iter().any(|x| *x == r2) { result_set.push(r2); } } diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index 72178500b54e..7e418c0061d3 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -21,7 +21,7 @@ use middle::typeck::infer::lattice::CombineFieldsLatticeMethods; use middle::typeck::infer::lub::Lub; use middle::typeck::infer::to_str::InferStr; use middle::typeck::infer::{TypeTrace, Subtype}; -use util::common::{indent, indenter}; +use util::common::{indenter}; use util::ppaux::bound_region_to_str; use extra::list::Nil; @@ -29,7 +29,6 @@ use extra::list; use syntax::abi::AbiSet; use syntax::ast; use syntax::ast::{Onceness, m_const, purity}; -use syntax::codemap::span; pub struct Sub(CombineFields); // "subtype", "subregion" etc @@ -200,7 +199,7 @@ impl Combine for Sub { // or new variables: match *tainted_region { ty::re_infer(ty::ReVar(ref vid)) => { - if new_vars.iter().any_(|x| x == vid) { loop; } + if new_vars.iter().any(|x| x == vid) { loop; } } _ => { if *tainted_region == skol { loop; } diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs index a930570dd173..60fc485c4db5 100644 --- a/src/librustc/rustc.rs +++ b/src/librustc/rustc.rs @@ -9,7 +9,7 @@ // except according to those terms. #[link(name = "rustc", - vers = "0.7", + vers = "0.8-pre", uuid = "0ce89b41-2f92-459e-bbc1-8f5fe32f16cf", url = "https://github.com/mozilla/rust/tree/master/src/rustc")]; @@ -19,6 +19,7 @@ #[allow(non_implicitly_copyable_typarams)]; #[allow(non_camel_case_types)]; +#[allow(non_uppercase_statics)]; #[deny(deprecated_pattern)]; extern mod extra; @@ -211,7 +212,7 @@ pub fn run_compiler(args: &~[~str], demitter: diagnostic::Emitter) { let lint_flags = vec::append(getopts::opt_strs(matches, "W"), getopts::opt_strs(matches, "warn")); - let show_lint_options = lint_flags.iter().any_(|x| x == &~"help") || + let show_lint_options = lint_flags.iter().any(|x| x == &~"help") || (opt_present(matches, "W") && lint_flags.is_empty()); if show_lint_options { @@ -220,7 +221,7 @@ pub fn run_compiler(args: &~[~str], demitter: diagnostic::Emitter) { } let r = getopts::opt_strs(matches, "Z"); - if r.iter().any_(|x| x == &~"help") { + if r.iter().any(|x| x == &~"help") { describe_debug_flags(); return; } diff --git a/src/librustc/util/enum_set.rs b/src/librustc/util/enum_set.rs index 2bdb6583b230..3ce645e012b7 100644 --- a/src/librustc/util/enum_set.rs +++ b/src/librustc/util/enum_set.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::iterator::Iterator; #[deriving(Eq, IterBytes)] pub struct EnumSet { @@ -73,6 +74,10 @@ impl EnumSet { } return true; } + + pub fn iter(&self) -> EnumSetIterator { + EnumSetIterator::new(self.bits) + } } impl Sub, EnumSet> for EnumSet { @@ -93,11 +98,43 @@ impl BitAnd, EnumSet> for EnumSet { } } +pub struct EnumSetIterator { + priv index: uint, + priv bits: uint, +} + +impl EnumSetIterator { + fn new(bits: uint) -> EnumSetIterator { + EnumSetIterator { index: 0, bits: bits } + } +} + +impl Iterator for EnumSetIterator { + fn next(&mut self) -> Option { + if (self.bits == 0) { + return None; + } + + while (self.bits & 1) == 0 { + self.index += 1; + self.bits >>= 1; + } + let elem = CLike::from_uint(self.index); + self.index += 1; + self.bits >>= 1; + Some(elem) + } + + fn size_hint(&self) -> (uint, Option) { + let exact = self.bits.population_count(); + (exact, Some(exact)) + } +} + #[cfg(test)] mod test { use std::cast; - use std::iter; use util::enum_set::*; @@ -199,25 +236,58 @@ mod test { } /////////////////////////////////////////////////////////////////////////// - // each + // iter / each + + #[test] + fn test_iterator() { + let mut e1: EnumSet = EnumSet::empty(); + + let elems: ~[Foo] = e1.iter().collect(); + assert_eq!(~[], elems) + + e1.add(A); + let elems: ~[Foo] = e1.iter().collect(); + assert_eq!(~[A], elems) + + e1.add(C); + let elems: ~[Foo] = e1.iter().collect(); + assert_eq!(~[A,C], elems) + + e1.add(C); + let elems: ~[Foo] = e1.iter().collect(); + assert_eq!(~[A,C], elems) + + e1.add(B); + let elems: ~[Foo] = e1.iter().collect(); + assert_eq!(~[A,B,C], elems) + } #[test] fn test_each() { let mut e1: EnumSet = EnumSet::empty(); - assert_eq!(~[], iter::FromIter::from_iter::(|f| e1.each(f))) + assert_eq!(~[], collect(e1)) e1.add(A); - assert_eq!(~[A], iter::FromIter::from_iter::(|f| e1.each(f))) + assert_eq!(~[A], collect(e1)) e1.add(C); - assert_eq!(~[A,C], iter::FromIter::from_iter::(|f| e1.each(f))) + assert_eq!(~[A,C], collect(e1)) e1.add(C); - assert_eq!(~[A,C], iter::FromIter::from_iter::(|f| e1.each(f))) + assert_eq!(~[A,C], collect(e1)) e1.add(B); - assert_eq!(~[A,B,C], iter::FromIter::from_iter::(|f| e1.each(f))) + assert_eq!(~[A,B,C], collect(e1)) + } + + fn collect(e: EnumSet) -> ~[Foo] { + let mut elems = ~[]; + e.each(|elem| { + elems.push(elem); + true + }); + elems } /////////////////////////////////////////////////////////////////////////// @@ -234,12 +304,15 @@ mod test { e2.add(C); let e_union = e1 | e2; - assert_eq!(~[A,B,C], iter::FromIter::from_iter::(|f| e_union.each(f))) + let elems: ~[Foo] = e_union.iter().collect(); + assert_eq!(~[A,B,C], elems) let e_intersection = e1 & e2; - assert_eq!(~[C], iter::FromIter::from_iter::(|f| e_intersection.each(f))) + let elems: ~[Foo] = e_intersection.iter().collect(); + assert_eq!(~[C], elems) let e_subtract = e1 - e2; - assert_eq!(~[A], iter::FromIter::from_iter::(|f| e_subtract.each(f))) + let elems: ~[Foo] = e_subtract.iter().collect(); + assert_eq!(~[A], elems) } } diff --git a/src/librustdoc/attr_parser.rs b/src/librustdoc/attr_parser.rs index 7655e173e4e2..e61f8d6d7433 100644 --- a/src/librustdoc/attr_parser.rs +++ b/src/librustdoc/attr_parser.rs @@ -45,9 +45,9 @@ pub fn parse_crate(attrs: ~[ast::attribute]) -> CrateAttrs { } pub fn parse_desc(attrs: ~[ast::attribute]) -> Option<~str> { - let doc_strs = do doc_metas(attrs).filter_mapped |meta| { - attr::get_meta_item_value_str(*meta).map(|s| s.to_owned()) - }; + let doc_strs = do doc_metas(attrs).consume_iter().filter_map |meta| { + attr::get_meta_item_value_str(meta).map(|s| s.to_owned()) + }.collect::<~[~str]>(); if doc_strs.is_empty() { None } else { @@ -57,7 +57,7 @@ pub fn parse_desc(attrs: ~[ast::attribute]) -> Option<~str> { pub fn parse_hidden(attrs: ~[ast::attribute]) -> bool { let r = doc_metas(attrs); - do r.iter().any_ |meta| { + do r.iter().any |meta| { match attr::get_meta_item_list(*meta) { Some(metas) => { let hiddens = attr::find_meta_items_by_name(metas, "hidden"); diff --git a/src/librustdoc/demo.rs b/src/librustdoc/demo.rs index b6728e00fe41..3393133bc186 100644 --- a/src/librustdoc/demo.rs +++ b/src/librustdoc/demo.rs @@ -23,7 +23,7 @@ /// The base price of a muffin on a non-holiday -static price_of_a_muffin: float = 70f; +static PRICE_OF_A_MUFFIN: float = 70f; struct WaitPerson { hair_color: ~str diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs index 74d5d4674137..3fd6ad169987 100644 --- a/src/librustdoc/desc_to_brief_pass.rs +++ b/src/librustdoc/desc_to_brief_pass.rs @@ -87,11 +87,11 @@ pub fn extract(desc: Option<~str>) -> Option<~str> { } fn parse_desc(desc: ~str) -> Option<~str> { - static max_brief_len: uint = 120u; + static MAX_BRIEF_LEN: uint = 120u; match first_sentence(copy desc) { Some(first_sentence) => { - if first_sentence.len() <= max_brief_len { + if first_sentence.len() <= MAX_BRIEF_LEN { Some(first_sentence) } else { None @@ -141,7 +141,7 @@ fn first_sentence_(s: &str) -> ~str { pub fn paragraphs(s: &str) -> ~[~str] { let mut whitespace_lines = 0; let mut accum = ~""; - let paras = do s.any_line_iter().fold(~[]) |paras, line| { + let mut paras = do s.any_line_iter().fold(~[]) |paras, line| { let mut res = paras; if line.is_whitespace() { @@ -166,11 +166,8 @@ pub fn paragraphs(s: &str) -> ~[~str] { res }; - if !accum.is_empty() { - paras + [accum] - } else { - paras - } + if !accum.is_empty() { paras.push(accum); } + paras } #[cfg(test)] diff --git a/src/librustdoc/doc.rs b/src/librustdoc/doc.rs index b45550c06e44..ffb4642be810 100644 --- a/src/librustdoc/doc.rs +++ b/src/librustdoc/doc.rs @@ -13,8 +13,6 @@ use doc; -use std::vec; - pub type AstId = int; #[deriving(Eq)] @@ -186,87 +184,64 @@ impl Doc { } } +macro_rules! filt_mapper { + ($vec:expr, $pat:pat) => { + do ($vec).iter().filter_map |thing| { + match thing { + &$pat => Some(copy *x), + _ => None + } + }.collect() + } +} + +macro_rules! md { + ($id:ident) => { + filt_mapper!(self.items, $id(ref x)) + } +} /// Some helper methods on ModDoc, mostly for testing impl ModDoc { pub fn mods(&self) -> ~[ModDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - ModTag(ModDoc) => Some(ModDoc), - _ => None - } - } + md!(ModTag) } pub fn nmods(&self) -> ~[NmodDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - NmodTag(nModDoc) => Some(nModDoc), - _ => None - } - } + md!(NmodTag) } pub fn fns(&self) -> ~[FnDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - FnTag(FnDoc) => Some(FnDoc), - _ => None - } - } + md!(FnTag) } pub fn consts(&self) -> ~[ConstDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - ConstTag(ConstDoc) => Some(ConstDoc), - _ => None - } - } + md!(ConstTag) } pub fn enums(&self) -> ~[EnumDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - EnumTag(EnumDoc) => Some(EnumDoc), - _ => None - } - } + md!(EnumTag) } pub fn traits(&self) -> ~[TraitDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - TraitTag(TraitDoc) => Some(TraitDoc), - _ => None - } - } + md!(TraitTag) } pub fn impls(&self) -> ~[ImplDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - ImplTag(ImplDoc) => Some(ImplDoc), - _ => None - } - } + md!(ImplTag) } pub fn types(&self) -> ~[TyDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - TyTag(TyDoc) => Some(TyDoc), - _ => None - } - } + md!(TyTag) } pub fn structs(&self) -> ~[StructDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - StructTag(StructDoc) => Some(StructDoc), - _ => None - } - } + md!(StructTag) + } +} + +macro_rules! pu { + ($id:ident) => { + filt_mapper!(*self, ItemPage($id(ref x))) } } @@ -284,75 +259,35 @@ pub trait PageUtils { impl PageUtils for ~[Page] { fn mods(&self) -> ~[ModDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(ModTag(ModDoc)) => Some(ModDoc), - _ => None - } - } + pu!(ModTag) } fn nmods(&self) -> ~[NmodDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(NmodTag(nModDoc)) => Some(nModDoc), - _ => None - } - } + pu!(NmodTag) } fn fns(&self) -> ~[FnDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(FnTag(FnDoc)) => Some(FnDoc), - _ => None - } - } + pu!(FnTag) } fn consts(&self) -> ~[ConstDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(ConstTag(ConstDoc)) => Some(ConstDoc), - _ => None - } - } + pu!(ConstTag) } fn enums(&self) -> ~[EnumDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(EnumTag(EnumDoc)) => Some(EnumDoc), - _ => None - } - } + pu!(EnumTag) } fn traits(&self) -> ~[TraitDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(TraitTag(TraitDoc)) => Some(TraitDoc), - _ => None - } - } + pu!(TraitTag) } fn impls(&self) -> ~[ImplDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(ImplTag(ImplDoc)) => Some(ImplDoc), - _ => None - } - } + pu!(ImplTag) } fn types(&self) -> ~[TyDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(TyTag(TyDoc)) => Some(TyDoc), - _ => None - } - } + pu!(TyTag) } } diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs index d5d2b4ce6286..01b77a985fed 100644 --- a/src/librustdoc/extract.rs +++ b/src/librustdoc/extract.rs @@ -15,7 +15,6 @@ use astsrv; use doc::ItemUtils; use doc; -use std::vec; use syntax::ast; use syntax::parse::token::{ident_interner, ident_to_str}; use syntax::parse::token; @@ -83,7 +82,7 @@ fn moddoc_from_mod( ) -> doc::ModDoc { doc::ModDoc { item: itemdoc, - items: do vec::filter_mapped(module_.items) |item| { + items: do module_.items.iter().filter_map |item| { let ItemDoc = mk_itemdoc(item.id, to_str(item.ident)); match copy item.node { ast::item_mod(m) => { @@ -133,7 +132,7 @@ fn moddoc_from_mod( } _ => None } - }, + }.collect(), index: None } } diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index 0705a5c17233..f800a8ab946f 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -172,7 +172,7 @@ pub fn header_kind(doc: doc::ItemTag) -> ~str { } pub fn header_name(doc: doc::ItemTag) -> ~str { - let fullpath = (doc.path() + [doc.name()]).connect("::"); + let fullpath = (doc.path() + &[doc.name()]).connect("::"); match &doc { &doc::ModTag(_) if doc.id() != syntax::ast::crate_node_id => { fullpath diff --git a/src/librustdoc/markdown_writer.rs b/src/librustdoc/markdown_writer.rs index 9621ea0892b9..d757547d8f76 100644 --- a/src/librustdoc/markdown_writer.rs +++ b/src/librustdoc/markdown_writer.rs @@ -163,7 +163,7 @@ pub fn make_filename( } } doc::ItemPage(doc) => { - (doc.path() + [doc.name()]).connect("_") + (doc.path() + &[doc.name()]).connect("_") } } }; diff --git a/src/librustdoc/page_pass.rs b/src/librustdoc/page_pass.rs index 508cf302ede5..83a0d44978ec 100644 --- a/src/librustdoc/page_pass.rs +++ b/src/librustdoc/page_pass.rs @@ -128,13 +128,12 @@ fn fold_mod( fn strip_mod(doc: doc::ModDoc) -> doc::ModDoc { doc::ModDoc { - items: do doc.items.filtered |item| { - match *item { - doc::ModTag(_) => false, - doc::NmodTag(_) => false, + items: do doc.items.iter().filter |item| { + match **item { + doc::ModTag(_) | doc::NmodTag(_) => false, _ => true } - }, + }.transform(|x| copy *x).collect::<~[doc::ItemTag]>(), .. copy doc } } diff --git a/src/librustdoc/prune_hidden_pass.rs b/src/librustdoc/prune_hidden_pass.rs index 484eb8c7980d..96c5df10680c 100644 --- a/src/librustdoc/prune_hidden_pass.rs +++ b/src/librustdoc/prune_hidden_pass.rs @@ -41,9 +41,9 @@ fn fold_mod( let doc = fold::default_any_fold_mod(fold, doc); doc::ModDoc { - items: do doc.items.filtered |ItemTag| { - !is_hidden(fold.ctxt.clone(), ItemTag.item()) - }, + items: do doc.items.iter().filter |item_tag| { + !is_hidden(fold.ctxt.clone(), item_tag.item()) + }.transform(|x| copy *x).collect(), .. doc } } diff --git a/src/librustdoc/prune_private_pass.rs b/src/librustdoc/prune_private_pass.rs index cb7da801e96e..aeb6e02f244f 100644 --- a/src/librustdoc/prune_private_pass.rs +++ b/src/librustdoc/prune_private_pass.rs @@ -80,7 +80,7 @@ fn strip_priv_methods( methods: &[@ast::method], item_vis: ast::visibility ) -> doc::ImplDoc { - let methods = do (&doc.methods).filtered |method| { + let methods = do doc.methods.iter().filter |method| { let ast_method = do methods.iter().find_ |m| { extract::to_str(m.ident) == method.name }; @@ -91,7 +91,7 @@ fn strip_priv_methods( ast::private => false, ast::inherited => item_vis == ast::public } - }; + }.transform(|x| copy *x).collect(); doc::ImplDoc { methods: methods, @@ -106,9 +106,9 @@ fn fold_mod( let doc = fold::default_any_fold_mod(fold, doc); doc::ModDoc { - items: doc.items.filtered(|ItemTag| { - match ItemTag { - &doc::ImplTag(ref doc) => { + items: doc.items.iter().filter(|item_tag| { + match item_tag { + & &doc::ImplTag(ref doc) => { if doc.trait_types.is_empty() { // This is an associated impl. We have already pruned the // non-visible methods. If there are any left then @@ -123,10 +123,10 @@ fn fold_mod( } } _ => { - is_visible(fold.ctxt.clone(), ItemTag.item()) + is_visible(fold.ctxt.clone(), item_tag.item()) } } - }), + }).transform(|x| copy *x).collect(), .. doc } } diff --git a/src/librustdoc/rustdoc.rs b/src/librustdoc/rustdoc.rs index 3659d24a254f..d12f85dcc44f 100644 --- a/src/librustdoc/rustdoc.rs +++ b/src/librustdoc/rustdoc.rs @@ -11,7 +11,7 @@ //! Rustdoc - The Rust documentation generator #[link(name = "rustdoc", - vers = "0.7", + vers = "0.8-pre", uuid = "f8abd014-b281-484d-a0c3-26e3de8e2412", url = "https://github.com/mozilla/rust/tree/master/src/rustdoc")]; @@ -64,7 +64,7 @@ pub mod util; pub fn main() { let args = os::args(); - if args.iter().any_(|x| "-h" == *x) || args.iter().any_(|x| "--help" == *x) { + if args.iter().any(|x| "-h" == *x) || args.iter().any(|x| "--help" == *x) { config::usage(); return; } diff --git a/src/librustdoc/tystr_pass.rs b/src/librustdoc/tystr_pass.rs index e40bdb532da9..40c662e3a09e 100644 --- a/src/librustdoc/tystr_pass.rs +++ b/src/librustdoc/tystr_pass.rs @@ -94,7 +94,7 @@ fn fold_const( do astsrv::exec(srv) |ctxt| { match ctxt.ast_map.get_copy(&doc.id()) { ast_map::node_item(@ast::item { - node: ast::item_static(ty, _, _), _ + node: ast::item_static(ref ty, _, _), _ }, _) => { pprust::ty_to_str(ty, extract::interner()) } @@ -245,12 +245,12 @@ fn fold_impl( do astsrv::exec(srv) |ctxt| { match ctxt.ast_map.get_copy(&doc.id()) { ast_map::node_item(@ast::item { - node: ast::item_impl(ref generics, opt_trait_type, self_ty, _), _ + node: ast::item_impl(ref generics, ref opt_trait_type, ref self_ty, _), _ }, _) => { let bounds = pprust::generics_to_str(generics, extract::interner()); let bounds = if bounds.is_empty() { None } else { Some(bounds) }; let trait_types = opt_trait_type.map_default(~[], |p| { - ~[pprust::path_to_str(p.path, extract::interner())] + ~[pprust::path_to_str(&p.path, extract::interner())] }); (bounds, trait_types, @@ -285,15 +285,14 @@ fn fold_type( match ctxt.ast_map.get_copy(&doc.id()) { ast_map::node_item(@ast::item { ident: ident, - node: ast::item_ty(ty, ref params), _ + node: ast::item_ty(ref ty, ref params), _ }, _) => { Some(fmt!( "type %s%s = %s", to_str(ident), pprust::generics_to_str(params, extract::interner()), - pprust::ty_to_str(ty, - extract::interner()) + pprust::ty_to_str(ty, extract::interner()) )) } _ => fail!("expected type") diff --git a/src/librusti/program.rs b/src/librusti/program.rs index 869b3472422b..e15cc04fa9b7 100644 --- a/src/librusti/program.rs +++ b/src/librusti/program.rs @@ -196,21 +196,7 @@ impl Program { // up front, disable lots of annoying lints, then include all global // state such as items, view items, and extern mods. let mut code = fmt!(" - #[allow(ctypes)]; - #[allow(heap_memory)]; - #[allow(implicit_copies)]; - #[allow(managed_heap_memory)]; - #[allow(non_camel_case_types)]; - #[allow(owned_heap_memory)]; - #[allow(path_statement)]; - #[allow(unrecognized_lint)]; - #[allow(unused_imports)]; - #[allow(while_true)]; - #[allow(unused_variable)]; - #[allow(dead_assignment)]; - #[allow(unused_unsafe)]; - #[allow(unused_mut)]; - #[allow(unreachable_code)]; + #[allow(warnings)]; extern mod extra; %s // extern mods diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc deleted file mode 100644 index bbc4b9ff7197..000000000000 --- a/src/librusti/rusti.rc +++ /dev/null @@ -1,667 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/*! - * rusti - A REPL using the JIT backend - * - * Rusti works by serializing state between lines of input. This means that each - * line can be run in a separate task, and the only limiting factor is that all - * local bound variables are encodable. - * - * This is accomplished by feeding in generated input to rustc for execution in - * the JIT compiler. Currently input actually gets fed in three times to get - * information about the program. - * - * - Pass #1 - * In this pass, the input is simply thrown at the parser and the input comes - * back. This validates the structure of the program, and at this stage the - * global items (fns, structs, impls, traits, etc.) are filtered from the - * input into the "global namespace". These declarations shadow all previous - * declarations of an item by the same name. - * - * - Pass #2 - * After items have been stripped, the remaining input is passed to rustc - * along with all local variables declared (initialized to nothing). This pass - * runs up to typechecking. From this, we can learn about the types of each - * bound variable, what variables are bound, and also ensure that all the - * types are encodable (the input can actually be run). - * - * - Pass #3 - * Finally, a program is generated to deserialize the local variable state, - * run the code input, and then reserialize all bindings back into a local - * hash map. Once this code runs, the input has fully been run and the REPL - * waits for new input. - * - * Encoding/decoding is done with EBML, and there is simply a map of ~str -> - * ~[u8] maintaining the values of each local binding (by name). - */ - -#[link(name = "rusti", - vers = "0.7", - uuid = "7fb5bf52-7d45-4fee-8325-5ad3311149fc", - url = "https://github.com/mozilla/rust/tree/master/src/rusti")]; - -#[license = "MIT/ASL2"]; -#[crate_type = "lib"]; - -extern mod extra; -extern mod rustc; -extern mod syntax; - -use std::{libc, io, os, task, vec}; -use std::cell::Cell; -use extra::rl; - -use rustc::driver::{driver, session}; -use syntax::{ast, diagnostic}; -use syntax::ast_util::*; -use syntax::parse::token; -use syntax::print::pprust; - -use program::Program; -use utils::*; - -mod program; -pub mod utils; - -/** - * A structure shared across REPL instances for storing history - * such as statements and view items. I wish the AST was sendable. - */ -pub struct Repl { - prompt: ~str, - binary: ~str, - running: bool, - lib_search_paths: ~[~str], - - program: Program, -} - -// Action to do after reading a :command -enum CmdAction { - action_none, - action_run_line(~str), -} - -/// Run an input string in a Repl, returning the new Repl. -fn run(mut repl: Repl, input: ~str) -> Repl { - // Build some necessary rustc boilerplate for compiling things - let binary = repl.binary.to_managed(); - let options = @session::options { - crate_type: session::unknown_crate, - binary: binary, - addl_lib_search_paths: @mut repl.lib_search_paths.map(|p| Path(*p)), - jit: true, - .. copy *session::basic_options() - }; - // Because we assume that everything is encodable (and assert so), add some - // extra helpful information if the error crops up. Otherwise people are - // bound to be very confused when they find out code is running that they - // never typed in... - let sess = driver::build_session(options, |cm, msg, lvl| { - diagnostic::emit(cm, msg, lvl); - if msg.contains("failed to find an implementation of trait") && - msg.contains("extra::serialize::Encodable") { - diagnostic::emit(cm, - "Currrently rusti serializes bound locals between \ - different lines of input. This means that all \ - values of local variables need to be encodable, \ - and this type isn't encodable", - diagnostic::note); - } - }); - let intr = token::get_ident_interner(); - - // - // Stage 1: parse the input and filter it into the program (as necessary) - // - debug!("parsing: %s", input); - let crate = parse_input(sess, binary, input); - let mut to_run = ~[]; // statements to run (emitted back into code) - let new_locals = @mut ~[]; // new locals being defined - let mut result = None; // resultant expression (to print via pp) - do find_main(crate, sess) |blk| { - // Fish out all the view items, be sure to record 'extern mod' items - // differently beause they must appear before all 'use' statements - for blk.node.view_items.iter().advance |vi| { - let s = do with_pp(intr) |pp, _| { - pprust::print_view_item(pp, *vi); - }; - match vi.node { - ast::view_item_extern_mod(*) => { - repl.program.record_extern(s); - } - ast::view_item_use(*) => { repl.program.record_view_item(s); } - } - } - - // Iterate through all of the block's statements, inserting them into - // the correct portions of the program - for blk.node.stmts.iter().advance |stmt| { - let s = do with_pp(intr) |pp, _| { pprust::print_stmt(pp, *stmt); }; - match stmt.node { - ast::stmt_decl(d, _) => { - match d.node { - ast::decl_item(it) => { - let name = sess.str_of(it.ident); - match it.node { - // Structs are treated specially because to make - // them at all usable they need to be decorated - // with #[deriving(Encoable, Decodable)] - ast::item_struct(*) => { - repl.program.record_struct(name, s); - } - // Item declarations are hoisted out of main() - _ => { repl.program.record_item(name, s); } - } - } - - // Local declarations must be specially dealt with, - // record all local declarations for use later on - ast::decl_local(l) => { - let mutbl = l.node.is_mutbl; - do each_binding(l) |path, _| { - let s = do with_pp(intr) |pp, _| { - pprust::print_path(pp, path, false); - }; - new_locals.push((s, mutbl)); - } - to_run.push(s); - } - } - } - - // run statements with expressions (they have effects) - ast::stmt_mac(*) | ast::stmt_semi(*) | ast::stmt_expr(*) => { - to_run.push(s); - } - } - } - result = do blk.node.expr.map_consume |e| { - do with_pp(intr) |pp, _| { pprust::print_expr(pp, e); } - }; - } - // return fast for empty inputs - if to_run.len() == 0 && result.is_none() { - return repl; - } - - // - // Stage 2: run everything up to typeck to learn the types of the new - // variables introduced into the program - // - info!("Learning about the new types in the program"); - repl.program.set_cache(); // before register_new_vars (which changes them) - let input = to_run.connect("\n"); - let test = repl.program.test_code(input, &result, *new_locals); - debug!("testing with ^^^^^^ %?", (||{ println(test) })()); - let dinput = driver::str_input(test.to_managed()); - let cfg = driver::build_configuration(sess, binary, &dinput); - let outputs = driver::build_output_filenames(&dinput, &None, &None, [], sess); - let (crate, tcx) = driver::compile_upto(sess, copy cfg, &dinput, - driver::cu_typeck, Some(outputs)); - // Once we're typechecked, record the types of all local variables defined - // in this input - do find_main(crate.expect("crate after cu_typeck"), sess) |blk| { - repl.program.register_new_vars(blk, tcx.expect("tcx after cu_typeck")); - } - - // - // Stage 3: Actually run the code in the JIT - // - info!("actually running code"); - let code = repl.program.code(input, &result); - debug!("actually running ^^^^^^ %?", (||{ println(code) })()); - let input = driver::str_input(code.to_managed()); - let cfg = driver::build_configuration(sess, binary, &input); - let outputs = driver::build_output_filenames(&input, &None, &None, [], sess); - let sess = driver::build_session(options, diagnostic::emit); - driver::compile_upto(sess, cfg, &input, driver::cu_everything, - Some(outputs)); - - // - // Stage 4: Inform the program that computation is done so it can update all - // local variable bindings. - // - info!("cleaning up after code"); - repl.program.consume_cache(); - - return repl; - - fn parse_input(sess: session::Session, binary: @str, - input: &str) -> @ast::crate { - let code = fmt!("fn main() {\n %s \n}", input); - let input = driver::str_input(code.to_managed()); - let cfg = driver::build_configuration(sess, binary, &input); - let outputs = driver::build_output_filenames(&input, &None, &None, [], sess); - let (crate, _) = driver::compile_upto(sess, cfg, &input, - driver::cu_parse, Some(outputs)); - crate.expect("parsing should return a crate") - } - - fn find_main(crate: @ast::crate, sess: session::Session, - f: &fn(&ast::blk)) { - for crate.node.module.items.iter().advance |item| { - match item.node { - ast::item_fn(_, _, _, _, ref blk) => { - if item.ident == sess.ident_of("main") { - return f(blk); - } - } - _ => {} - } - } - fail!("main function was expected somewhere..."); - } -} - -// Compiles a crate given by the filename as a library if the compiled -// version doesn't exist or is older than the source file. Binary is -// the name of the compiling executable. Returns Some(true) if it -// successfully compiled, Some(false) if the crate wasn't compiled -// because it already exists and is newer than the source file, or -// None if there were compile errors. -fn compile_crate(src_filename: ~str, binary: ~str) -> Option { - match do task::try { - let src_path = Path(src_filename); - let binary = binary.to_managed(); - let options = @session::options { - binary: binary, - addl_lib_search_paths: @mut ~[os::getcwd()], - .. copy *session::basic_options() - }; - let input = driver::file_input(copy src_path); - let sess = driver::build_session(options, diagnostic::emit); - *sess.building_library = true; - let cfg = driver::build_configuration(sess, binary, &input); - let outputs = driver::build_output_filenames( - &input, &None, &None, [], sess); - // If the library already exists and is newer than the source - // file, skip compilation and return None. - let mut should_compile = true; - let dir = os::list_dir_path(&Path(outputs.out_filename.dirname())); - let maybe_lib_path = do dir.iter().find_ |file| { - // The actual file's name has a hash value and version - // number in it which is unknown at this time, so looking - // for a file that matches out_filename won't work, - // instead we guess which file is the library by matching - // the prefix and suffix of out_filename to files in the - // directory. - let file_str = file.filename().get(); - file_str.starts_with(outputs.out_filename.filestem().get()) - && file_str.ends_with(outputs.out_filename.filetype().get()) - }; - match maybe_lib_path { - Some(lib_path) => { - let (src_mtime, _) = src_path.get_mtime().get(); - let (lib_mtime, _) = lib_path.get_mtime().get(); - if lib_mtime >= src_mtime { - should_compile = false; - } - }, - None => { }, - } - if (should_compile) { - println(fmt!("compiling %s...", src_filename)); - driver::compile_upto(sess, cfg, &input, driver::cu_everything, - Some(outputs)); - true - } else { false } - } { - Ok(true) => Some(true), - Ok(false) => Some(false), - Err(_) => None, - } -} - -/// Tries to get a line from rl after outputting a prompt. Returns -/// None if no input was read (e.g. EOF was reached). -fn get_line(use_rl: bool, prompt: &str) -> Option<~str> { - if use_rl { - let result = unsafe { rl::read(prompt) }; - - match result { - None => None, - Some(line) => { - unsafe { rl::add_history(line) }; - Some(line) - } - } - } else { - if io::stdin().eof() { - None - } else { - Some(io::stdin().read_line()) - } - } -} - -/// Run a command, e.g. :clear, :exit, etc. -fn run_cmd(repl: &mut Repl, _in: @io::Reader, _out: @io::Writer, - cmd: ~str, args: ~[~str], use_rl: bool) -> CmdAction { - let mut action = action_none; - match cmd { - ~"exit" => repl.running = false, - ~"clear" => { - repl.program.clear(); - - // XXX: Win32 version of linenoise can't do this - //rl::clear(); - } - ~"help" => { - println( - ":{\\n ..lines.. \\n:}\\n - execute multiline command\n\ - :load ... - loads given crates as dynamic libraries\n\ - :clear - clear the bindings\n\ - :exit - exit from the repl\n\ - :help - show this message"); - } - ~"load" => { - let mut loaded_crates: ~[~str] = ~[]; - for args.iter().advance |arg| { - let (crate, filename) = - if arg.ends_with(".rs") || arg.ends_with(".rc") { - (arg.slice_to(arg.len() - 3).to_owned(), copy *arg) - } else { - (copy *arg, *arg + ".rs") - }; - match compile_crate(filename, copy repl.binary) { - Some(_) => loaded_crates.push(crate), - None => { } - } - } - for loaded_crates.iter().advance |crate| { - let crate_path = Path(*crate); - let crate_dir = crate_path.dirname(); - repl.program.record_extern(fmt!("extern mod %s;", *crate)); - if !repl.lib_search_paths.iter().any_(|x| x == &crate_dir) { - repl.lib_search_paths.push(crate_dir); - } - } - if loaded_crates.is_empty() { - println("no crates loaded"); - } else { - println(fmt!("crates loaded: %s", - loaded_crates.connect(", "))); - } - } - ~"{" => { - let mut multiline_cmd = ~""; - let mut end_multiline = false; - while (!end_multiline) { - match get_line(use_rl, "rusti| ") { - None => fail!("unterminated multiline command :{ .. :}"), - Some(line) => { - if line.trim() == ":}" { - end_multiline = true; - } else { - multiline_cmd.push_str(line); - multiline_cmd.push_char('\n'); - } - } - } - } - action = action_run_line(multiline_cmd); - } - _ => println(~"unknown cmd: " + cmd) - } - return action; -} - -/// Executes a line of input, which may either be rust code or a -/// :command. Returns a new Repl if it has changed. -pub fn run_line(repl: &mut Repl, in: @io::Reader, out: @io::Writer, line: ~str, - use_rl: bool) - -> Option { - if line.starts_with(":") { - // drop the : and the \n (one byte each) - let full = line.slice(1, line.len()); - let split: ~[~str] = full.word_iter().transform(|s| s.to_owned()).collect(); - let len = split.len(); - - if len > 0 { - let cmd = copy split[0]; - - if !cmd.is_empty() { - let args = if len > 1 { - vec::slice(split, 1, len).to_owned() - } else { ~[] }; - - match run_cmd(repl, in, out, cmd, args, use_rl) { - action_none => { } - action_run_line(multiline_cmd) => { - if !multiline_cmd.is_empty() { - return run_line(repl, in, out, multiline_cmd, use_rl); - } - } - } - return None; - } - } - } - - let line = Cell::new(line); - let r = Cell::new(copy *repl); - let result = do task::try { - run(r.take(), line.take()) - }; - - if result.is_ok() { - return Some(result.get()); - } - return None; -} - -pub fn main() { - let args = os::args(); - let in = io::stdin(); - let out = io::stdout(); - let mut repl = Repl { - prompt: ~"rusti> ", - binary: copy args[0], - running: true, - lib_search_paths: ~[], - - program: Program::new(), - }; - - let istty = unsafe { libc::isatty(libc::STDIN_FILENO as i32) } != 0; - - // only print this stuff if the user is actually typing into rusti - if istty { - println("WARNING: The Rust REPL is experimental and may be"); - println("unstable. If you encounter problems, please use the"); - println("compiler instead. Type :help for help."); - - unsafe { - do rl::complete |line, suggest| { - if line.starts_with(":") { - suggest(~":clear"); - suggest(~":exit"); - suggest(~":help"); - suggest(~":load"); - } - } - } - } - - while repl.running { - match get_line(istty, repl.prompt) { - None => break, - Some(line) => { - if line.is_empty() { - if istty { - println("()"); - } - loop; - } - match run_line(&mut repl, in, out, line, istty) { - Some(new_repl) => repl = new_repl, - None => { } - } - } - } - } -} - -//#[cfg(test)] -#[cfg(ignore)] // FIXME #7541 doesn't work under cross-compile -mod tests { - use std::io; - use std::iterator::IteratorUtil; - use program::Program; - use super::*; - - fn repl() -> Repl { - Repl { - prompt: ~"rusti> ", - binary: ~"rusti", - running: true, - lib_search_paths: ~[], - program: Program::new(), - } - } - - fn run_program(prog: &str) { - let mut r = repl(); - for prog.split_iter('\n').advance |cmd| { - let result = run_line(&mut r, io::stdin(), io::stdout(), - cmd.to_owned(), false); - r = result.expect(fmt!("the command '%s' failed", cmd)); - } - } - - #[test] - // FIXME: #7220 rusti on 32bit mac doesn't work. - #[cfg(not(target_word_size="32", - target_os="macos"))] - fn run_all() { - // FIXME(#7071): - // By default, unit tests are run in parallel. Rusti, on the other hand, - // does not enjoy doing this. I suspect that it is because the LLVM - // bindings are not thread-safe (when running parallel tests, some tests - // were triggering assertions in LLVM (or segfaults). Hence, this - // function exists to run everything serially (sadface). - // - // To get some interesting output, run with RUST_LOG=rusti::tests - - debug!("hopefully this runs"); - run_program(""); - - debug!("regression test for #5937"); - run_program("use std::hashmap;"); - - debug!("regression test for #5784"); - run_program("let a = 3;"); - - // XXX: can't spawn new tasks because the JIT code is cleaned up - // after the main function is done. - // debug!("regression test for #5803"); - // run_program(" - // spawn( || println(\"Please don't segfault\") ); - // do spawn { println(\"Please?\"); } - // "); - - debug!("inferred integers are usable"); - run_program("let a = 2;\n()\n"); - run_program(" - let a = 3; - let b = 4u; - assert!((a as uint) + b == 7) - "); - - debug!("local variables can be shadowed"); - run_program(" - let a = 3; - let a = 5; - assert!(a == 5) - "); - - debug!("strings are usable"); - run_program(" - let a = ~\"\"; - let b = \"\"; - let c = @\"\"; - let d = a + b + c; - assert!(d.len() == 0); - "); - - debug!("vectors are usable"); - run_program(" - let a = ~[1, 2, 3]; - let b = &[1, 2, 3]; - let c = @[1, 2, 3]; - let d = a + b + c; - assert!(d.len() == 9); - let e: &[int] = []; - "); - - debug!("structs are usable"); - run_program(" - struct A{ a: int } - let b = A{ a: 3 }; - assert!(b.a == 3) - "); - - debug!("mutable variables"); - run_program(" - let mut a = 3; - a = 5; - let mut b = std::hashmap::HashSet::new::(); - b.insert(a); - assert!(b.contains(&5)) - assert!(b.len() == 1) - "); - - debug!("functions are cached"); - run_program(" - fn fib(x: int) -> int { if x < 2 {x} else { fib(x - 1) + fib(x - 2) } } - let a = fib(3); - let a = a + fib(4); - assert!(a == 5) - "); - - debug!("modules are cached"); - run_program(" - mod b { pub fn foo() -> uint { 3 } } - assert!(b::foo() == 3) - "); - - debug!("multiple function definitions are allowed"); - run_program(" - fn f() {} - fn f() {} - f() - "); - - debug!("multiple item definitions are allowed"); - run_program(" - fn f() {} - mod f {} - struct f; - enum f {} - fn f() {} - f() - "); - } - - #[test] - // FIXME: #7220 rusti on 32bit mac doesn't work. - #[cfg(not(target_word_size="32", - target_os="macos"))] - fn exit_quits() { - let mut r = repl(); - assert!(r.running); - let result = run_line(&mut r, io::stdin(), io::stdout(), - ~":exit", false); - assert!(result.is_none()); - assert!(!r.running); - } -} diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs index f91d99322390..2ba881f5a04a 100644 --- a/src/librusti/rusti.rs +++ b/src/librusti/rusti.rs @@ -44,7 +44,7 @@ */ #[link(name = "rusti", - vers = "0.7", + vers = "0.8-pre", uuid = "7fb5bf52-7d45-4fee-8325-5ad3311149fc", url = "https://github.com/mozilla/rust/tree/master/src/rusti")]; @@ -132,7 +132,7 @@ fn run(mut repl: Repl, input: ~str) -> Repl { // differently beause they must appear before all 'use' statements for blk.node.view_items.iter().advance |vi| { let s = do with_pp(intr) |pp, _| { - pprust::print_view_item(pp, *vi); + pprust::print_view_item(pp, vi); }; match vi.node { ast::view_item_extern_mod(*) => { @@ -381,7 +381,7 @@ fn run_cmd(repl: &mut Repl, _in: @io::Reader, _out: @io::Writer, let crate_path = Path(*crate); let crate_dir = crate_path.dirname(); repl.program.record_extern(fmt!("extern mod %s;", *crate)); - if !repl.lib_search_paths.iter().any_(|x| x == &crate_dir) { + if !repl.lib_search_paths.iter().any(|x| x == &crate_dir) { repl.lib_search_paths.push(crate_dir); } } @@ -511,8 +511,7 @@ pub fn main() { } } -//#[cfg(test)] -#[cfg(ignore)] // FIXME #7541 doesn't work under cross-compile +#[cfg(test)] mod tests { use std::io; use std::iterator::IteratorUtil; @@ -530,8 +529,9 @@ mod tests { } // FIXME: #7220 rusti on 32bit mac doesn't work. - #[cfg(not(target_word_size="32"))] - #[cfg(not(target_os="macos"))] + // FIXME: #7641 rusti on 32bit linux cross compile doesn't work + // FIXME: #7115 re-enable once LLVM has been upgraded + #[cfg(thiswillneverbeacfgflag)] fn run_program(prog: &str) { let mut r = repl(); for prog.split_iter('\n').advance |cmd| { @@ -540,7 +540,6 @@ mod tests { r = result.expect(fmt!("the command '%s' failed", cmd)); } } - #[cfg(target_word_size="32", target_os="macos")] fn run_program(_: &str) {} #[test] @@ -668,8 +667,10 @@ mod tests { fn f() {} f() "); + } - debug!("simultaneous definitions + expressions are allowed"); + #[test] + fn simultaneous_definition_and_expression() { run_program(" let a = 3; a as u8 "); diff --git a/src/librusti/utils.rs b/src/librusti/utils.rs index 0ac0f5a3c4cb..3932df1db847 100644 --- a/src/librusti/utils.rs +++ b/src/librusti/utils.rs @@ -14,14 +14,14 @@ use syntax::print::pp; use syntax::print::pprust; use syntax::parse::token; -pub fn each_binding(l: @ast::local, f: @fn(@ast::Path, ast::node_id)) { +pub fn each_binding(l: @ast::local, f: @fn(&ast::Path, ast::node_id)) { use syntax::visit; let vt = visit::mk_simple_visitor( @visit::SimpleVisitor { visit_pat: |pat| { match pat.node { - ast::pat_ident(_, path, _) => { + ast::pat_ident(_, ref path, _) => { f(path, pat.id); } _ => {} diff --git a/src/librustpkg/api.rs b/src/librustpkg/api.rs index c36c6390a759..5233b87f7e4f 100644 --- a/src/librustpkg/api.rs +++ b/src/librustpkg/api.rs @@ -14,10 +14,8 @@ use package_id::*; use package_source::*; use version::Version; -use std::option::*; use std::os; use std::hashmap::*; -use std::path::*; /// Convenience functions intended for calling from pkg.rs diff --git a/src/librustpkg/messages.rs b/src/librustpkg/messages.rs index 43d727c2989a..96c99a7a0f17 100644 --- a/src/librustpkg/messages.rs +++ b/src/librustpkg/messages.rs @@ -10,18 +10,17 @@ use extra::term; use std::io; -use std::result::*; pub fn note(msg: &str) { - pretty_message(msg, "note: ", term::color::green, io::stdout()) + pretty_message(msg, "note: ", term::color::GREEN, io::stdout()) } pub fn warn(msg: &str) { - pretty_message(msg, "warning: ", term::color::yellow, io::stdout()) + pretty_message(msg, "warning: ", term::color::YELLOW, io::stdout()) } pub fn error(msg: &str) { - pretty_message(msg, "error: ", term::color::red, io::stdout()) + pretty_message(msg, "error: ", term::color::RED, io::stdout()) } fn pretty_message<'a>(msg: &'a str, prefix: &'a str, color: term::color::Color, out: @io::Writer) { diff --git a/src/librustpkg/package_source.rs b/src/librustpkg/package_source.rs index 24c1bb9b200f..b2f608bd352a 100644 --- a/src/librustpkg/package_source.rs +++ b/src/librustpkg/package_source.rs @@ -11,7 +11,6 @@ use target::*; use package_id::PkgId; use std::path::Path; -use std::option::*; use std::{os, run, str}; use context::*; use crate::Crate; diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs index 6371d7263461..b8f77ceececd 100644 --- a/src/librustpkg/path_util.rs +++ b/src/librustpkg/path_util.rs @@ -29,9 +29,9 @@ fn push_if_exists(vec: &mut ~[Path], p: &Path) { } #[cfg(windows)] -static path_entry_separator: &'static str = ";"; +static PATH_ENTRY_SEPARATOR: &'static str = ";"; #[cfg(not(windows))] -static path_entry_separator: &'static str = ":"; +static PATH_ENTRY_SEPARATOR: &'static str = ":"; /// Returns the value of RUST_PATH, as a list /// of Paths. Includes default entries for, if they exist: @@ -42,7 +42,7 @@ pub fn rust_path() -> ~[Path] { let mut env_rust_path: ~[Path] = match os::getenv("RUST_PATH") { Some(env_path) => { let env_path_components: ~[&str] = - env_path.split_str_iter(path_entry_separator).collect(); + env_path.split_str_iter(PATH_ENTRY_SEPARATOR).collect(); env_path_components.map(|&s| Path(s)) } None => ~[] @@ -56,12 +56,12 @@ pub fn rust_path() -> ~[Path] { env_rust_path } -pub static u_rwx: i32 = (S_IRUSR | S_IWUSR | S_IXUSR) as i32; +pub static U_RWX: i32 = (S_IRUSR | S_IWUSR | S_IXUSR) as i32; /// Creates a directory that is readable, writeable, /// and executable by the user. Returns true iff creation /// succeeded. -pub fn make_dir_rwx(p: &Path) -> bool { os::make_dir(p, u_rwx) } +pub fn make_dir_rwx(p: &Path) -> bool { os::make_dir(p, U_RWX) } // n.b. The next three functions ignore the package version right // now. Should fix that. @@ -318,7 +318,7 @@ fn target_file_in_workspace(pkgid: &PkgId, workspace: &Path, Lib => "lib", Main | Test | Bench => "bin" }; let result = workspace.push(subdir); - if !os::path_exists(&result) && !mkdir_recursive(&result, u_rwx) { + if !os::path_exists(&result) && !mkdir_recursive(&result, U_RWX) { cond.raise((copy result, fmt!("target_file_in_workspace couldn't \ create the %s dir (pkgid=%s, workspace=%s, what=%?, where=%?", subdir, pkgid.to_str(), workspace.to_str(), what, where))); @@ -335,7 +335,7 @@ pub fn build_pkg_id_in_workspace(pkgid: &PkgId, workspace: &Path) -> Path { // n.b. Should actually use a target-specific // subdirectory of build/ result = result.push_rel(&*pkgid.local_path); - if os::path_exists(&result) || os::mkdir_recursive(&result, u_rwx) { + if os::path_exists(&result) || os::mkdir_recursive(&result, U_RWX) { result } else { diff --git a/src/librustpkg/rustpkg.rs b/src/librustpkg/rustpkg.rs index 8ca8ae1b1edf..4e4570961e75 100644 --- a/src/librustpkg/rustpkg.rs +++ b/src/librustpkg/rustpkg.rs @@ -11,7 +11,7 @@ // rustpkg - a package manager and build system for Rust #[link(name = "rustpkg", - vers = "0.7", + vers = "0.8-pre", uuid = "25de5e6e-279e-4a20-845c-4cabae92daaf", url = "https://github.com/mozilla/rust/tree/master/src/librustpkg")]; @@ -38,7 +38,7 @@ use syntax::{ast, diagnostic}; use util::*; use messages::*; use path_util::{build_pkg_id_in_workspace, first_pkgid_src_in_workspace}; -use path_util::{u_rwx, rust_path}; +use path_util::{U_RWX, rust_path}; use path_util::{built_executable_in_workspace, built_library_in_workspace}; use path_util::{target_executable_in_workspace, target_library_in_workspace}; use workspace::{each_pkg_parent_workspace, pkg_parent_workspaces}; @@ -374,7 +374,7 @@ impl CtxMethods for Ctx { for maybe_executable.iter().advance |exec| { debug!("Copying: %s -> %s", exec.to_str(), target_exec.to_str()); - if !(os::mkdir_recursive(&target_exec.dir_path(), u_rwx) && + if !(os::mkdir_recursive(&target_exec.dir_path(), U_RWX) && os::copy_file(exec, &target_exec)) { cond.raise((copy *exec, copy target_exec)); } @@ -383,7 +383,7 @@ impl CtxMethods for Ctx { let target_lib = (copy target_lib).expect(fmt!("I built %s but apparently \ didn't install it!", lib.to_str())); debug!("Copying: %s -> %s", lib.to_str(), target_lib.to_str()); - if !(os::mkdir_recursive(&target_lib.dir_path(), u_rwx) && + if !(os::mkdir_recursive(&target_lib.dir_path(), U_RWX) && os::copy_file(lib, &target_lib)) { cond.raise((copy *lib, copy target_lib)); } diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index 4acc621e7be2..251783577df8 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -21,7 +21,7 @@ use package_source::*; use version::{ExactRevision, NoVersion, Version}; use path_util::{target_executable_in_workspace, target_library_in_workspace, target_test_in_workspace, target_bench_in_workspace, - make_dir_rwx, u_rwx, library_in_workspace, + make_dir_rwx, U_RWX, library_in_workspace, built_bench_in_workspace, built_test_in_workspace, built_library_in_workspace, built_executable_in_workspace, installed_library_in_workspace, rust_path}; @@ -78,7 +78,7 @@ fn mk_workspace(workspace: &Path, short_name: &LocalPath, version: &Version) -> // include version number in directory name let package_dir = workspace.push("src").push(fmt!("%s-%s", short_name.to_str(), version.to_str())); - assert!(os::mkdir_recursive(&package_dir, u_rwx)); + assert!(os::mkdir_recursive(&package_dir, U_RWX)); package_dir } @@ -92,7 +92,7 @@ fn mk_temp_workspace(short_name: &LocalPath, version: &Version) -> Path { os::path_is_dir(&package_dir)); // Create main, lib, test, and bench files debug!("mk_workspace: creating %s", package_dir.to_str()); - assert!(os::mkdir_recursive(&package_dir, u_rwx)); + assert!(os::mkdir_recursive(&package_dir, U_RWX)); debug!("Created %s and does it exist? %?", package_dir.to_str(), os::path_is_dir(&package_dir)); // Create main, lib, test, and bench files @@ -181,7 +181,7 @@ fn create_local_package_in(pkgid: &PkgId, pkgdir: &Path) -> Path { let package_dir = pkgdir.push("src").push(pkgid.to_str()); // Create main, lib, test, and bench files - assert!(os::mkdir_recursive(&package_dir, u_rwx)); + assert!(os::mkdir_recursive(&package_dir, U_RWX)); debug!("Created %s and does it exist? %?", package_dir.to_str(), os::path_is_dir(&package_dir)); // Create main, lib, test, and bench files @@ -585,9 +585,9 @@ fn rust_path_test() { fn rust_path_contents() { let dir = mkdtemp(&os::tmpdir(), "rust_path").expect("rust_path_contents failed"); let abc = &dir.push("A").push("B").push("C"); - assert!(os::mkdir_recursive(&abc.push(".rust"), u_rwx)); - assert!(os::mkdir_recursive(&abc.pop().push(".rust"), u_rwx)); - assert!(os::mkdir_recursive(&abc.pop().pop().push(".rust"), u_rwx)); + assert!(os::mkdir_recursive(&abc.push(".rust"), U_RWX)); + assert!(os::mkdir_recursive(&abc.pop().push(".rust"), U_RWX)); + assert!(os::mkdir_recursive(&abc.pop().pop().push(".rust"), U_RWX)); assert!(do os::change_dir_locked(&dir.push("A").push("B").push("C")) { let p = rust_path(); let cwd = os::getcwd().push(".rust"); @@ -626,14 +626,14 @@ fn install_remove() { command_line_test([~"install", ~"bar"], &dir); command_line_test([~"install", ~"quux"], &dir); let list_output = command_line_test_output([~"list"]); - assert!(list_output.iter().any_(|x| x == &~"foo")); - assert!(list_output.iter().any_(|x| x == &~"bar")); - assert!(list_output.iter().any_(|x| x == &~"quux")); + assert!(list_output.iter().any(|x| x == &~"foo")); + assert!(list_output.iter().any(|x| x == &~"bar")); + assert!(list_output.iter().any(|x| x == &~"quux")); command_line_test([~"remove", ~"foo"], &dir); let list_output = command_line_test_output([~"list"]); - assert!(!list_output.iter().any_(|x| x == &~"foo")); - assert!(list_output.iter().any_(|x| x == &~"bar")); - assert!(list_output.iter().any_(|x| x == &~"quux")); + assert!(!list_output.iter().any(|x| x == &~"foo")); + assert!(list_output.iter().any(|x| x == &~"bar")); + assert!(list_output.iter().any(|x| x == &~"quux")); } #[test] @@ -699,7 +699,7 @@ fn test_versions() { command_line_test([~"install", ~"foo#0.1"], &workspace); let output = command_line_test_output([~"list"]); // make sure output includes versions - assert!(!output.iter().any_(|x| x == &~"foo#0.2")); + assert!(!output.iter().any(|x| x == &~"foo#0.2")); } #[test] diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 26e26add3dc2..900ef4896ca1 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::{libc, os, result, str}; +use std::{os, result}; use rustc::driver::{driver, session}; use rustc::metadata::filesearch; use extra::getopts::groups::getopts; @@ -28,7 +28,7 @@ use search::find_library_in_search_path; use path_util::target_library_in_workspace; pub use target::{OutputType, Main, Lib, Bench, Test}; -static Commands: &'static [&'static str] = +static COMMANDS: &'static [&'static str] = &["build", "clean", "do", "info", "install", "prefer", "test", "uninstall", "unprefer"]; @@ -55,7 +55,7 @@ pub fn root() -> Path { } pub fn is_cmd(cmd: &str) -> bool { - Commands.iter().any_(|&c| c == cmd) + COMMANDS.iter().any(|&c| c == cmd) } struct ListenerFn { @@ -77,9 +77,9 @@ fn fold_mod(_ctx: @mut ReadyCtx, fold: @fold::ast_fold) -> ast::_mod { fn strip_main(item: @ast::item) -> @ast::item { @ast::item { - attrs: do item.attrs.filtered |attr| { - "main" != attr::get_attr_name(attr) - }, + attrs: do item.attrs.iter().filter_map |attr| { + if "main" != attr::get_attr_name(attr) {Some(*attr)} else {None} + }.collect(), .. copy *item } } @@ -379,6 +379,7 @@ pub fn link_exe(_src: &Path, _dest: &Path) -> bool { #[cfg(target_os = "freebsd")] #[cfg(target_os = "macos")] pub fn link_exe(src: &Path, dest: &Path) -> bool { + use std::{libc, str}; unsafe { do str::as_c_str(src.to_str()) |src_buf| { do str::as_c_str(dest.to_str()) |dest_buf| { @@ -417,4 +418,4 @@ mod test { // tjc: cheesy fn debug_flags() -> ~[~str] { ~[] } -// static debug_flags: ~[~str] = ~[~"-Z", ~"time-passes"]; +// static DEBUG_FLAGS: ~[~str] = ~[~"-Z", ~"time-passes"]; diff --git a/src/librustpkg/workspace.rs b/src/librustpkg/workspace.rs index dd2cf445302a..5876dbdc9dea 100644 --- a/src/librustpkg/workspace.rs +++ b/src/librustpkg/workspace.rs @@ -34,6 +34,7 @@ pub fn each_pkg_parent_workspace(pkgid: &PkgId, action: &fn(&Path) -> bool) -> b } pub fn pkg_parent_workspaces(pkgid: &PkgId) -> ~[Path] { - rust_path().filtered(|ws| - workspace_contains_package_id(pkgid, ws)) + rust_path().consume_iter() + .filter(|ws| workspace_contains_package_id(pkgid, ws)) + .collect() } diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index 75d0fe7a0b29..dfd39af093d9 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -17,8 +17,7 @@ use kinds::Copy; use option::Option; use sys; use uint; -use vec; -use vec::ImmutableVector; +use vec::{ImmutableVector, OwnedVector}; /// Code for dealing with @-vectors. This is pretty incomplete, and /// contains a bunch of duplication from the code for ~-vectors. @@ -142,7 +141,7 @@ pub fn to_managed_consume(v: ~[T]) -> @[T] { let mut av = @[]; unsafe { raw::reserve(&mut av, v.len()); - do vec::consume(v) |_i, x| { + for v.consume_iter().advance |x| { raw::push(&mut av, x); } transmute(av) @@ -160,13 +159,14 @@ pub fn to_managed(v: &[T]) -> @[T] { #[cfg(not(test))] pub mod traits { use at_vec::append; + use vec::Vector; use kinds::Copy; use ops::Add; - impl<'self,T:Copy> Add<&'self [T],@[T]> for @[T] { + impl<'self,T:Copy, V: Vector> Add for @[T] { #[inline] - fn add(&self, rhs: & &'self [T]) -> @[T] { - append(*self, (*rhs)) + fn add(&self, rhs: &V) -> @[T] { + append(*self, rhs.as_slice()) } } } @@ -335,7 +335,7 @@ mod test { #[test] fn append_test() { - assert_eq!(@[1,2,3] + [4,5,6], @[1,2,3,4,5,6]); + assert_eq!(@[1,2,3] + &[4,5,6], @[1,2,3,4,5,6]); } #[test] diff --git a/src/libstd/bool.rs b/src/libstd/bool.rs index e6be164099bf..b0b586df4b58 100644 --- a/src/libstd/bool.rs +++ b/src/libstd/bool.rs @@ -122,6 +122,7 @@ pub fn xor(a: bool, b: bool) -> bool { (a && !b) || (!a && b) } * ~~~ {.rust} * rusti> std::bool::implies(true, true) * true +* ~~~ * * ~~~ {.rust} * rusti> std::bool::implies(true, false) diff --git a/src/libstd/char.rs b/src/libstd/char.rs index 6a9555f4efcd..47473c2faba6 100644 --- a/src/libstd/char.rs +++ b/src/libstd/char.rs @@ -82,7 +82,8 @@ pub fn is_uppercase(c: char) -> bool { general_category::Lu(c) } /// #[inline] pub fn is_whitespace(c: char) -> bool { - ('\x09' <= c && c <= '\x0d') + c == ' ' + || ('\x09' <= c && c <= '\x0d') || general_category::Zs(c) || general_category::Zl(c) || general_category::Zp(c) diff --git a/src/libstd/either.rs b/src/libstd/either.rs index b6da93f9d40a..8b9b3102831c 100644 --- a/src/libstd/either.rs +++ b/src/libstd/either.rs @@ -73,7 +73,7 @@ pub fn rights(eithers: &[Either]) -> ~[U] { pub fn partition(eithers: ~[Either]) -> (~[T], ~[U]) { let mut lefts: ~[T] = ~[]; let mut rights: ~[U] = ~[]; - do vec::consume(eithers) |_i, elt| { + for eithers.consume_iter().advance |elt| { match elt { Left(l) => lefts.push(l), Right(r) => rights.push(r) diff --git a/src/libstd/gc.rs b/src/libstd/gc.rs index c9e33219fa50..f92561edcb08 100644 --- a/src/libstd/gc.rs +++ b/src/libstd/gc.rs @@ -9,6 +9,7 @@ // except according to those terms. #[doc(hidden)]; +#[allow(non_uppercase_statics)]; /*! Precise garbage collector diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 85dca1154bc0..2d80dc2be152 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -24,7 +24,7 @@ use rand::RngUtil; use rand; use uint; use vec; -use vec::{ImmutableVector, MutableVector}; +use vec::{ImmutableVector, MutableVector, OwnedVector}; use kinds::Copy; use util::{replace, unreachable}; @@ -175,7 +175,8 @@ impl HashMap { vec::from_fn(new_capacity, |_| None)); self.size = 0; - do vec::consume(old_buckets) |_, bucket| { + // consume_rev_iter is more efficient + for old_buckets.consume_rev_iter().advance |bucket| { self.insert_opt_bucket(bucket); } } @@ -441,7 +442,7 @@ impl HashMap { vec::from_fn(INITIAL_CAPACITY, |_| None)); self.size = 0; - do vec::consume(buckets) |_, bucket| { + for buckets.consume_iter().advance |bucket| { match bucket { None => {}, Some(Bucket{key, value, _}) => { diff --git a/src/libstd/io.rs b/src/libstd/io.rs index bdcad15f45c4..38826dd411b6 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -917,7 +917,7 @@ fn convert_whence(whence: SeekStyle) -> i32 { impl Reader for *libc::FILE { fn read(&self, bytes: &mut [u8], len: uint) -> uint { unsafe { - do vec::as_mut_buf(bytes) |buf_p, buf_len| { + do bytes.as_mut_buf |buf_p, buf_len| { assert!(buf_len >= len); let count = libc::fread(buf_p as *mut c_void, 1u as size_t, @@ -1152,7 +1152,7 @@ impl Writer for Wrapper { impl Writer for *libc::FILE { fn write(&self, v: &[u8]) { unsafe { - do vec::as_imm_buf(v) |vbuf, len| { + do v.as_imm_buf |vbuf, len| { let nout = libc::fwrite(vbuf as *c_void, 1, len as size_t, @@ -1203,7 +1203,7 @@ impl Writer for fd_t { fn write(&self, v: &[u8]) { unsafe { let mut count = 0u; - do vec::as_imm_buf(v) |vbuf, len| { + do v.as_imm_buf |vbuf, len| { while count < len { let vb = ptr::offset(vbuf, count) as *c_void; let nout = libc::write(*self, vb, len as size_t); diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs index 4e598a4aa1cd..2092ae588d01 100644 --- a/src/libstd/iter.rs +++ b/src/libstd/iter.rs @@ -8,316 +8,19 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/*! Composable internal iterators - -Internal iterators are functions implementing the protocol used by the `for` loop. - -An internal iterator takes `fn(...) -> bool` as a parameter, with returning `false` used to signal -breaking out of iteration. The adaptors in the module work with any such iterator, not just ones -tied to specific traits. For example: +/*! Times trait ~~~ {.rust} -println(iter::to_vec(|f| uint::range(0, 20, f)).to_str()); +use iter::Times; +let ten = 10 as uint; +let mut accum = 0; +for ten.times { accum += 1; } ~~~ -An external iterator object implementing the interface in the `iterator` module can be used as an -internal iterator by calling the `advance` method. For example: - -~~~ {.rust} -let xs = [0u, 1, 2, 3, 4, 5]; -let ys = [30, 40, 50, 60]; -let mut it = xs.iter().chain(ys.iter()); -for it.advance |&x: &uint| { - println(x.to_str()); -} -~~~ - -Internal iterators provide a subset of the functionality of an external iterator. It's not possible -to interleave them to implement algorithms like `zip`, `union` and `merge`. However, they're often -much easier to implement. - */ -use cmp::Ord; -use option::{Option, Some, None}; -use num::{One, Zero}; -use ops::{Add, Mul}; - #[allow(missing_doc)] pub trait Times { fn times(&self, it: &fn() -> bool) -> bool; } -#[allow(missing_doc)] -pub trait FromIter { - /// Build a container with elements from an internal iterator. - /// - /// # Example: - /// - /// ~~~ {.rust} - /// let xs = ~[1, 2, 3]; - /// let ys: ~[int] = do FromIter::from_iter |f| { xs.iter().advance(|x| f(*x)) }; - /// assert_eq!(xs, ys); - /// ~~~ - pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> Self; -} - -/** - * Return true if `predicate` is true for any values yielded by an internal iterator. - * - * Example: - * - * ~~~ {.rust} - * let xs = ~[1u, 2, 3, 4, 5]; - * assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f))); - * assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f))); - * ~~~ - */ -#[inline] -pub fn any(predicate: &fn(T) -> bool, - iter: &fn(f: &fn(T) -> bool) -> bool) -> bool { - for iter |x| { - if predicate(x) { - return true; - } - } - return false; -} - -/** - * Return true if `predicate` is true for all values yielded by an internal iterator. - * - * # Example: - * - * ~~~ {.rust} - * assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f))); - * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f))); - * ~~~ - */ -#[inline] -pub fn all(predicate: &fn(T) -> bool, - iter: &fn(f: &fn(T) -> bool) -> bool) -> bool { - // If we ever break, iter will return false, so this will only return true - // if predicate returns true for everything. - iter(|x| predicate(x)) -} - -/** - * Return the first element where `predicate` returns `true`. Return `None` if no element is found. - * - * # Example: - * - * ~~~ {.rust} - * let xs = ~[1u, 2, 3, 4, 5, 6]; - * assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.iter().advance(f)).unwrap(), 4); - * ~~~ - */ -#[inline] -pub fn find(predicate: &fn(&T) -> bool, - iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { - for iter |x| { - if predicate(&x) { - return Some(x); - } - } - None -} - -/** - * Return the largest item yielded by an iterator. Return `None` if the iterator is empty. - * - * # Example: - * - * ~~~ {.rust} - * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; - * assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &15); - * ~~~ - */ -#[inline] -pub fn max(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { - let mut result = None; - for iter |x| { - match result { - Some(ref mut y) => { - if x > *y { - *y = x; - } - } - None => result = Some(x) - } - } - result -} - -/** - * Return the smallest item yielded by an iterator. Return `None` if the iterator is empty. - * - * # Example: - * - * ~~~ {.rust} - * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; - * assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &-5); - * ~~~ - */ -#[inline] -pub fn min(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { - let mut result = None; - for iter |x| { - match result { - Some(ref mut y) => { - if x < *y { - *y = x; - } - } - None => result = Some(x) - } - } - result -} - -/** - * Reduce an iterator to an accumulated value. - * - * # Example: - * - * ~~~ {.rust} - * assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10); - * ~~~ - */ -#[inline] -pub fn fold(start: T, iter: &fn(f: &fn(U) -> bool) -> bool, f: &fn(&mut T, U)) -> T { - let mut result = start; - for iter |x| { - f(&mut result, x); - } - result -} - -/** - * Reduce an iterator to an accumulated value. - * - * `fold_ref` is usable in some generic functions where `fold` is too lenient to type-check, but it - * forces the iterator to yield borrowed pointers. - * - * # Example: - * - * ~~~ {.rust} - * fn product>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T { - * fold_ref(One::one::(), iter, |a, x| *a = a.mul(x)) - * } - * ~~~ - */ -#[inline] -pub fn fold_ref(start: T, iter: &fn(f: &fn(&U) -> bool) -> bool, f: &fn(&mut T, &U)) -> T { - let mut result = start; - for iter |x| { - f(&mut result, x); - } - result -} - -/** - * Return the sum of the items yielding by an iterator. - * - * # Example: - * - * ~~~ {.rust} - * let xs: ~[int] = ~[1, 2, 3, 4]; - * assert_eq!(do sum |f| { xs.iter().advance(f) }, 10); - * ~~~ - */ -#[inline] -pub fn sum>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T { - fold_ref(Zero::zero::(), iter, |a, x| *a = a.add(x)) -} - -/** - * Return the product of the items yielded by an iterator. - * - * # Example: - * - * ~~~ {.rust} - * let xs: ~[int] = ~[1, 2, 3, 4]; - * assert_eq!(do product |f| { xs.iter().advance(f) }, 24); - * ~~~ - */ -#[inline] -pub fn product>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T { - fold_ref(One::one::(), iter, |a, x| *a = a.mul(x)) -} - -#[cfg(test)] -mod tests { - use super::*; - use prelude::*; - - use int; - use uint; - - #[test] - fn test_from_iter() { - let xs = ~[1, 2, 3]; - let ys: ~[int] = do FromIter::from_iter |f| { xs.iter().advance(|x| f(*x)) }; - assert_eq!(xs, ys); - } - - #[test] - fn test_any() { - let xs = ~[1u, 2, 3, 4, 5]; - assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f))); - assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f))); - } - - #[test] - fn test_all() { - assert!(all(|x: uint| x < 6, |f| uint::range(1, 6, f))); - assert!(!all(|x: uint| x < 5, |f| uint::range(1, 6, f))); - } - - #[test] - fn test_find() { - let xs = ~[1u, 2, 3, 4, 5, 6]; - assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.iter().advance(f)).unwrap(), 4); - } - - #[test] - fn test_max() { - let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; - assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &15); - } - - #[test] - fn test_min() { - let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; - assert_eq!(min(|f| xs.iter().advance(f)).unwrap(), &-5); - } - - #[test] - fn test_fold() { - assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10); - } - - #[test] - fn test_sum() { - let xs: ~[int] = ~[1, 2, 3, 4]; - assert_eq!(do sum |f| { xs.iter().advance(f) }, 10); - } - - #[test] - fn test_empty_sum() { - let xs: ~[int] = ~[]; - assert_eq!(do sum |f| { xs.iter().advance(f) }, 0); - } - - #[test] - fn test_product() { - let xs: ~[int] = ~[1, 2, 3, 4]; - assert_eq!(do product |f| { xs.iter().advance(f) }, 24); - } - - #[test] - fn test_empty_product() { - let xs: ~[int] = ~[]; - assert_eq!(do product |f| { xs.iter().advance(f) }, 1); - } -} diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 77befbf19aa9..4f5f1bd85c73 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -26,6 +26,7 @@ use option::{Option, Some, None}; use ops::{Add, Mul}; use cmp::Ord; use clone::Clone; +use uint; /// Conversion from an `Iterator` pub trait FromIterator> { @@ -43,7 +44,7 @@ pub trait Iterator { /// Return a lower bound and upper bound on the remaining length of the iterator. /// /// The common use case for the estimate is pre-allocating space to store the results. - fn size_hint(&self) -> (Option, Option) { (None, None) } + fn size_hint(&self) -> (uint, Option) { (0, None) } } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -244,6 +245,25 @@ pub trait IteratorUtil { fn flat_map_<'r, B, U: Iterator>(self, f: &'r fn(A) -> U) -> FlatMapIterator<'r, A, B, Self, U>; + /// Creates an iterator that calls a function with a reference to each + /// element before yielding it. This is often useful for debugging an + /// iterator pipeline. + /// + /// # Example + /// + /// ~~~ {.rust} + ///let xs = [1u, 4, 2, 3, 8, 9, 6]; + ///let sum = xs.iter() + /// .transform(|&x| x) + /// .peek_(|&x| debug!("filtering %u", x)) + /// .filter(|&x| x % 2 == 0) + /// .peek_(|&x| debug!("%u made it through", x)) + /// .sum(); + ///println(sum.to_str()); + /// ~~~ + // FIXME: #5898: should be called `peek` + fn peek_<'r>(self, f: &'r fn(&A)) -> PeekIterator<'r, A, Self>; + /// An adaptation of an external iterator to the for-loop protocol of rust. /// /// # Example @@ -337,16 +357,16 @@ pub trait IteratorUtil { /// ~~~ {.rust} /// let a = [1, 2, 3, 4, 5]; /// let mut it = a.iter(); - /// assert!(it.any_(|&x| *x == 3)); - /// assert!(!it.any_(|&x| *x == 3)); + /// assert!(it.any(|&x| *x == 3)); + /// assert!(!it.any(|&x| *x == 3)); /// ~~~ - fn any_(&mut self, f: &fn(A) -> bool) -> bool; + fn any(&mut self, f: &fn(A) -> bool) -> bool; /// Return the first element satisfying the specified predicate fn find_(&mut self, predicate: &fn(&A) -> bool) -> Option; /// Return the index of the first element satisfying the specified predicate - fn position_(&mut self, predicate: &fn(A) -> bool) -> Option; + fn position(&mut self, predicate: &fn(A) -> bool) -> Option; /// Count the number of elements satisfying the specified predicate fn count(&mut self, predicate: &fn(A) -> bool) -> uint; @@ -441,6 +461,12 @@ impl> IteratorUtil for T { FlatMapIterator{iter: self, f: f, subiter: None } } + // FIXME: #5898: should be called `peek` + #[inline] + fn peek_<'r>(self, f: &'r fn(&A)) -> PeekIterator<'r, A, T> { + PeekIterator{iter: self, f: f} + } + /// A shim implementing the `for` loop iteration protocol for iterator objects #[inline] fn advance(&mut self, f: &fn(A) -> bool) -> bool { @@ -503,7 +529,7 @@ impl> IteratorUtil for T { } #[inline] - fn any_(&mut self, f: &fn(A) -> bool) -> bool { + fn any(&mut self, f: &fn(A) -> bool) -> bool { for self.advance |x| { if f(x) { return true; } } false } @@ -519,7 +545,7 @@ impl> IteratorUtil for T { /// Return the index of the first element satisfying the specified predicate #[inline] - fn position_(&mut self, predicate: &fn(A) -> bool) -> Option { + fn position(&mut self, predicate: &fn(A) -> bool) -> Option { let mut i = 0; for self.advance |x| { if predicate(x) { @@ -684,18 +710,18 @@ impl, U: Iterator> Iterator for ChainIterator { } #[inline] - fn size_hint(&self) -> (Option, Option) { + fn size_hint(&self) -> (uint, Option) { let (a_lower, a_upper) = self.a.size_hint(); let (b_lower, b_upper) = self.b.size_hint(); - let lower = match (a_lower, b_lower) { - (Some(x), Some(y)) => Some(x + y), - (Some(x), None) => Some(x), - (None, Some(y)) => Some(y), - (None, None) => None + let lower = if uint::max_value - a_lower < b_lower { + uint::max_value + } else { + a_lower + b_lower }; let upper = match (a_upper, b_upper) { + (Some(x), Some(y)) if uint::max_value - x < y => Some(uint::max_value), (Some(x), Some(y)) => Some(x + y), _ => None }; @@ -719,6 +745,23 @@ impl, U: Iterator> Iterator<(A, B)> for ZipIterator None } } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + let (a_lower, a_upper) = self.a.size_hint(); + let (b_lower, b_upper) = self.b.size_hint(); + + let lower = cmp::min(a_lower, b_lower); + + let upper = match (a_upper, b_upper) { + (Some(x), Some(y)) => Some(cmp::min(x,y)), + (Some(x), None) => Some(x), + (None, Some(y)) => Some(y), + (None, None) => None + }; + + (lower, upper) + } } /// An iterator which maps the values of `iter` with `f` @@ -737,7 +780,7 @@ impl<'self, A, B, T: Iterator> Iterator for MapIterator<'self, A, B, T> { } #[inline] - fn size_hint(&self) -> (Option, Option) { + fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } } @@ -762,9 +805,9 @@ impl<'self, A, T: Iterator> Iterator for FilterIterator<'self, A, T> { } #[inline] - fn size_hint(&self) -> (Option, Option) { + fn size_hint(&self) -> (uint, Option) { let (_, upper) = self.iter.size_hint(); - (None, upper) // can't know a lower bound, due to the predicate + (0, upper) // can't know a lower bound, due to the predicate } } @@ -787,9 +830,9 @@ impl<'self, A, B, T: Iterator> Iterator for FilterMapIterator<'self, A, B, } #[inline] - fn size_hint(&self) -> (Option, Option) { + fn size_hint(&self) -> (uint, Option) { let (_, upper) = self.iter.size_hint(); - (None, upper) // can't know a lower bound, due to the predicate + (0, upper) // can't know a lower bound, due to the predicate } } @@ -812,6 +855,11 @@ impl> Iterator<(uint, A)> for EnumerateIterator { _ => None } } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + self.iter.size_hint() + } } /// An iterator which rejects elements while `predicate` is true @@ -844,6 +892,12 @@ impl<'self, A, T: Iterator> Iterator for SkipWhileIterator<'self, A, T> { } } } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } } /// An iterator which only accepts elements while `predicate` is true @@ -872,6 +926,12 @@ impl<'self, A, T: Iterator> Iterator for TakeWhileIterator<'self, A, T> { } } } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } } /// An iterator which skips over `n` elements of `iter`. @@ -905,6 +965,21 @@ impl> Iterator for SkipIterator { next } } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + let (lower, upper) = self.iter.size_hint(); + + let lower = if lower >= self.n { lower - self.n } else { 0 }; + + let upper = match upper { + Some(x) if x >= self.n => Some(x - self.n), + Some(_) => Some(0), + None => None + }; + + (lower, upper) + } } /// An iterator which only iterates over the first `n` iterations of `iter`. @@ -925,6 +1000,20 @@ impl> Iterator for TakeIterator { None } } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + let (lower, upper) = self.iter.size_hint(); + + let lower = cmp::min(lower, self.n); + + let upper = match upper { + Some(x) if x < self.n => Some(x), + _ => Some(self.n) + }; + + (lower, upper) + } } /// An iterator to maintain state while iterating another iterator @@ -941,6 +1030,12 @@ impl<'self, A, B, T: Iterator, St> Iterator for ScanIterator<'self, A, B, fn next(&mut self) -> Option { self.iter.next().chain(|a| (self.f)(&mut self.state, a)) } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the scan function + } } /// An iterator that maps each element to an iterator, @@ -971,6 +1066,32 @@ impl<'self, A, T: Iterator, B, U: Iterator> Iterator for } } +/// An iterator that calls a function with a reference to each +/// element before yielding it. +pub struct PeekIterator<'self, A, T> { + priv iter: T, + priv f: &'self fn(&A) +} + +impl<'self, A, T: Iterator> Iterator for PeekIterator<'self, A, T> { + #[inline] + fn next(&mut self) -> Option { + let next = self.iter.next(); + + match next { + Some(ref a) => (self.f)(a), + None => () + } + + next + } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + self.iter.size_hint() + } +} + /// An iterator which just modifies the contained state throughout iteration. pub struct UnfoldrIterator<'self, A, St> { priv f: &'self fn(&mut St) -> Option, @@ -1022,6 +1143,11 @@ impl + Clone> Iterator for Counter { self.state = self.state.add(&self.step); // FIXME: #6050 Some(result) } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + (uint::max_value, None) // Too bad we can't specify an infinite lower bound + } } #[cfg(test)] @@ -1161,6 +1287,20 @@ mod tests { assert_eq!(i, ys.len()); } + #[test] + fn test_peek() { + let xs = [1u, 2, 3, 4]; + let mut n = 0; + + let ys = xs.iter() + .transform(|&x| x) + .peek_(|_| n += 1) + .collect::<~[uint]>(); + + assert_eq!(n, xs.len()); + assert_eq!(xs, ys.as_slice()); + } + #[test] fn test_unfoldr() { fn count(st: &mut uint) -> Option { @@ -1237,6 +1377,43 @@ mod tests { assert_eq!(v.slice(0, 0).iter().transform(|&x| x).min(), None); } + #[test] + fn test_iterator_size_hint() { + let c = Counter::new(0, 1); + let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + let v2 = &[10, 11, 12]; + let vi = v.iter(); + + assert_eq!(c.size_hint(), (uint::max_value, None)); + assert_eq!(vi.size_hint(), (10, Some(10))); + + assert_eq!(c.take_(5).size_hint(), (5, Some(5))); + assert_eq!(c.skip(5).size_hint().second(), None); + assert_eq!(c.take_while(|_| false).size_hint(), (0, None)); + assert_eq!(c.skip_while(|_| false).size_hint(), (0, None)); + assert_eq!(c.enumerate().size_hint(), (uint::max_value, None)); + assert_eq!(c.chain_(vi.transform(|&i| i)).size_hint(), (uint::max_value, None)); + assert_eq!(c.zip(vi).size_hint(), (10, Some(10))); + assert_eq!(c.scan(0, |_,_| Some(0)).size_hint(), (0, None)); + assert_eq!(c.filter(|_| false).size_hint(), (0, None)); + assert_eq!(c.transform(|_| 0).size_hint(), (uint::max_value, None)); + assert_eq!(c.filter_map(|_| Some(0)).size_hint(), (0, None)); + + assert_eq!(vi.take_(5).size_hint(), (5, Some(5))); + assert_eq!(vi.take_(12).size_hint(), (10, Some(10))); + assert_eq!(vi.skip(3).size_hint(), (7, Some(7))); + assert_eq!(vi.skip(12).size_hint(), (0, Some(0))); + assert_eq!(vi.take_while(|_| false).size_hint(), (0, Some(10))); + assert_eq!(vi.skip_while(|_| false).size_hint(), (0, Some(10))); + assert_eq!(vi.enumerate().size_hint(), (10, Some(10))); + assert_eq!(vi.chain_(v2.iter()).size_hint(), (13, Some(13))); + assert_eq!(vi.zip(v2.iter()).size_hint(), (3, Some(3))); + assert_eq!(vi.scan(0, |_,_| Some(0)).size_hint(), (0, Some(10))); + assert_eq!(vi.filter(|_| false).size_hint(), (0, Some(10))); + assert_eq!(vi.transform(|i| i+1).size_hint(), (10, Some(10))); + assert_eq!(vi.filter_map(|_| Some(0)).size_hint(), (0, Some(10))); + } + #[test] fn test_collect() { let a = ~[1, 2, 3, 4, 5]; @@ -1256,10 +1433,10 @@ mod tests { #[test] fn test_any() { let v = ~&[1, 2, 3, 4, 5]; - assert!(v.iter().any_(|&x| x < 10)); - assert!(v.iter().any_(|&x| x.is_even())); - assert!(!v.iter().any_(|&x| x > 100)); - assert!(!v.slice(0, 0).iter().any_(|_| fail!())); + assert!(v.iter().any(|&x| x < 10)); + assert!(v.iter().any(|&x| x.is_even())); + assert!(!v.iter().any(|&x| x > 100)); + assert!(!v.slice(0, 0).iter().any(|_| fail!())); } #[test] @@ -1273,9 +1450,9 @@ mod tests { #[test] fn test_position() { let v = &[1, 3, 9, 27, 103, 14, 11]; - assert_eq!(v.iter().position_(|x| *x & 1 == 0).unwrap(), 5); - assert_eq!(v.iter().position_(|x| *x % 3 == 0).unwrap(), 1); - assert!(v.iter().position_(|x| *x % 12 == 0).is_none()); + assert_eq!(v.iter().position(|x| *x & 1 == 0).unwrap(), 5); + assert_eq!(v.iter().position(|x| *x % 3 == 0).unwrap(), 1); + assert!(v.iter().position(|x| *x % 12 == 0).is_none()); } #[test] diff --git a/src/libstd/kinds.rs b/src/libstd/kinds.rs index f350e1061680..6c16ecc0d4ef 100644 --- a/src/libstd/kinds.rs +++ b/src/libstd/kinds.rs @@ -18,7 +18,7 @@ intrinsic properties of the type. These classifications, often called They cannot be implemented by user code, but are instead implemented by the compiler automatically for the types to which they apply. -The 4 kinds are +The 3 kinds are * Copy - types that may be copied without allocation. This includes scalar types and managed pointers, and exludes owned pointers. It diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs index f4ea29b5c05e..14e719bc8dd4 100644 --- a/src/libstd/libc.rs +++ b/src/libstd/libc.rs @@ -64,6 +64,7 @@ */ #[allow(non_camel_case_types)]; +#[allow(non_uppercase_statics)]; #[allow(missing_doc)]; // Initial glob-exports mean that all the contents of all the modules diff --git a/src/libstd/num/cmath.rs b/src/libstd/num/cmath.rs index 96d3b79e3385..c89fc73693ca 100644 --- a/src/libstd/num/cmath.rs +++ b/src/libstd/num/cmath.rs @@ -9,6 +9,7 @@ // except according to those terms. #[allow(missing_doc)]; +#[allow(non_uppercase_statics)]; // function names are almost identical to C's libmath, a few have been // renamed, grep for "rename:" diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 0b6eb766b299..a84c27cd9188 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -10,6 +10,7 @@ //! Operations and constants for `f32` #[allow(missing_doc)]; +#[allow(non_uppercase_statics)]; use libc::c_int; use num::{Zero, One, strconv}; diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index c39c7a3a57d2..216963e04143 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -11,6 +11,7 @@ //! Operations and constants for `f64` #[allow(missing_doc)]; +#[allow(non_uppercase_statics)]; use libc::c_int; use num::{Zero, One, strconv}; diff --git a/src/libstd/num/float.rs b/src/libstd/num/float.rs index 7a6e3042e7b7..d73ff16c6f7b 100644 --- a/src/libstd/num/float.rs +++ b/src/libstd/num/float.rs @@ -21,6 +21,7 @@ // PORT this must match in width according to architecture #[allow(missing_doc)]; +#[allow(non_uppercase_statics)]; use f64; use libc::c_int; diff --git a/src/libstd/num/int.rs b/src/libstd/num/int.rs index d3c2733b47d5..d39b4b2b911f 100644 --- a/src/libstd/num/int.rs +++ b/src/libstd/num/int.rs @@ -10,6 +10,8 @@ //! Operations and constants for `int` +#[allow(non_uppercase_statics)]; + use num::BitCount; pub use self::generated::*; diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs index f152d60cb7a3..c2eebf9a3e41 100644 --- a/src/libstd/num/int_macros.rs +++ b/src/libstd/num/int_macros.rs @@ -14,6 +14,8 @@ macro_rules! int_module (($T:ty, $bits:expr) => (mod generated { +#[allow(non_uppercase_statics)]; + use num::{ToStrRadix, FromStrRadix}; use num::{Zero, One, strconv}; use prelude::*; diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index f6dff4267b7a..337d804ce732 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -101,12 +101,12 @@ impl_NumStrConv_Integer!(u64) // Special value strings as [u8] consts. -static inf_buf: [u8, ..3] = ['i' as u8, 'n' as u8, 'f' as u8]; -static positive_inf_buf: [u8, ..4] = ['+' as u8, 'i' as u8, 'n' as u8, +static INF_BUF: [u8, ..3] = ['i' as u8, 'n' as u8, 'f' as u8]; +static POS_INF_BUF: [u8, ..4] = ['+' as u8, 'i' as u8, 'n' as u8, 'f' as u8]; -static negative_inf_buf: [u8, ..4] = ['-' as u8, 'i' as u8, 'n' as u8, +static NEG_INF_BUF: [u8, ..4] = ['-' as u8, 'i' as u8, 'n' as u8, 'f' as u8]; -static nan_buf: [u8, ..3] = ['N' as u8, 'a' as u8, 'N' as u8]; +static NAN_BUF: [u8, ..3] = ['N' as u8, 'a' as u8, 'N' as u8]; /** * Converts an integral number to its string representation as a byte vector. @@ -506,15 +506,15 @@ pub fn from_str_bytes_common+ } if special { - if buf == inf_buf || buf == positive_inf_buf { + if buf == INF_BUF || buf == POS_INF_BUF { return NumStrConv::inf(); - } else if buf == negative_inf_buf { + } else if buf == NEG_INF_BUF { if negative { return NumStrConv::neg_inf(); } else { return None; } - } else if buf == nan_buf { + } else if buf == NAN_BUF { return NumStrConv::NaN(); } } diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs index 25e338fcd0f6..d185b2a05a8c 100644 --- a/src/libstd/num/uint_macros.rs +++ b/src/libstd/num/uint_macros.rs @@ -14,6 +14,8 @@ macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => (mod generated { +#[allow(non_uppercase_statics)]; + use num::BitCount; use num::{ToStrRadix, FromStrRadix}; use num::{Zero, One, strconv}; diff --git a/src/libstd/option.rs b/src/libstd/option.rs index 643812312582..fb9962f8a44e 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -161,7 +161,7 @@ impl Option { /// Filters an optional value using given function. #[inline(always)] - pub fn filtered<'a>(self, f: &fn(t: &'a T) -> bool) -> Option { + pub fn filtered(self, f: &fn(t: &T) -> bool) -> Option { match self { Some(x) => if(f(&x)) {Some(x)} else {None}, None => None @@ -170,10 +170,16 @@ impl Option { /// Maps a `some` value from one type to another by reference #[inline] - pub fn map<'a, U>(&self, f: &fn(&'a T) -> U) -> Option { + pub fn map<'a, U>(&'a self, f: &fn(&'a T) -> U) -> Option { match *self { Some(ref x) => Some(f(x)), None => None } } + /// Maps a `some` value from one type to another by a mutable reference + #[inline] + pub fn map_mut<'a, U>(&'a mut self, f: &fn(&'a mut T) -> U) -> Option { + match *self { Some(ref mut x) => Some(f(x)), None => None } + } + /// As `map`, but consumes the option and gives `f` ownership to avoid /// copying. #[inline] diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 20c4346d6187..c26020dd06d5 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -92,7 +92,7 @@ pub fn as_c_charp(s: &str, f: &fn(*c_char) -> T) -> T { pub fn fill_charp_buf(f: &fn(*mut c_char, size_t) -> bool) -> Option<~str> { let mut buf = vec::from_elem(TMPBUF_SZ, 0u8 as c_char); - do vec::as_mut_buf(buf) |b, sz| { + do buf.as_mut_buf |b, sz| { if f(b, sz as size_t) { unsafe { Some(str::raw::from_buf(b as *u8)) @@ -122,7 +122,7 @@ pub mod win32 { while !done { let mut k: DWORD = 0; let mut buf = vec::from_elem(n as uint, 0u16); - do vec::as_mut_buf(buf) |b, _sz| { + do buf.as_mut_buf |b, _sz| { k = f(b, TMPBUF_SZ as DWORD); if k == (0 as DWORD) { done = true; @@ -147,7 +147,7 @@ pub mod win32 { let mut t = s.to_utf16(); // Null terminate before passing on. t.push(0u16); - vec::as_imm_buf(t, |buf, _len| f(buf)) + t.as_imm_buf(|buf, _len| f(buf)) } } @@ -778,9 +778,9 @@ pub fn list_dir(p: &Path) -> ~[~str] { strings } } - do get_list(p).filtered |filename| { - *filename != ~"." && *filename != ~".." - } + do get_list(p).consume_iter().filter |filename| { + "." != *filename && ".." != *filename + }.collect() } } @@ -938,7 +938,7 @@ pub fn copy_file(from: &Path, to: &Path) -> bool { let mut done = false; let mut ok = true; while !done { - do vec::as_mut_buf(buf) |b, _sz| { + do buf.as_mut_buf |b, _sz| { let nread = libc::fread(b as *mut c_void, 1u as size_t, bufsize as size_t, istream); @@ -1694,7 +1694,7 @@ mod tests { let s = ~"hello"; let mut buf = s.as_bytes_with_null().to_owned(); let len = buf.len(); - do vec::as_mut_buf(buf) |b, _len| { + do buf.as_mut_buf |b, _len| { assert_eq!(libc::fwrite(b as *c_void, 1u as size_t, (s.len() + 1u) as size_t, ostream), len as size_t) diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index d560ce621eac..db534cca971a 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -47,7 +47,7 @@ pub use cmp::{Eq, ApproxEq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Great pub use char::Char; pub use container::{Container, Mutable, Map, Set}; pub use hash::Hash; -pub use iter::{Times, FromIter}; +pub use iter::{Times}; pub use iterator::{Iterator, IteratorUtil, OrdIterator}; pub use num::{Num, NumCast}; pub use num::{Orderable, Signed, Unsigned, Round}; @@ -72,7 +72,7 @@ pub use tuple::{CloneableTuple10, CloneableTuple11, CloneableTuple12}; pub use tuple::{ImmutableTuple2, ImmutableTuple3, ImmutableTuple4, ImmutableTuple5}; pub use tuple::{ImmutableTuple6, ImmutableTuple7, ImmutableTuple8, ImmutableTuple9}; pub use tuple::{ImmutableTuple10, ImmutableTuple11, ImmutableTuple12}; -pub use vec::{VectorVector, CopyableVector, ImmutableVector}; +pub use vec::{Vector, VectorVector, CopyableVector, ImmutableVector}; pub use vec::{ImmutableEqVector, ImmutableTotalOrdVector, ImmutableCopyableVector}; pub use vec::{OwnedVector, OwnedCopyableVector,OwnedEqVector, MutableVector}; pub use io::{Reader, ReaderUtil, Writer, WriterUtil}; diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index 473f56ddd798..aee6f1bd204e 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -406,7 +406,7 @@ pub mod ptr_tests { do str::as_c_str(s1) |p1| { do str::as_c_str(s2) |p2| { let v = ~[p0, p1, p2, null()]; - do vec::as_imm_buf(v) |vp, len| { + do v.as_imm_buf |vp, len| { assert_eq!(unsafe { buf_len(vp) }, 3u); assert_eq!(len, 4u); } diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs index 5f96e38a55af..5054763d742b 100644 --- a/src/libstd/rand.rs +++ b/src/libstd/rand.rs @@ -157,7 +157,7 @@ impl Rand for f32 { } } -static scale : f64 = (u32::max_value as f64) + 1.0f64; +static SCALE : f64 = (u32::max_value as f64) + 1.0f64; impl Rand for f64 { #[inline] fn rand(rng: &mut R) -> f64 { @@ -165,7 +165,7 @@ impl Rand for f64 { let u2 = rng.next() as f64; let u3 = rng.next() as f64; - ((u1 / scale + u2) / scale + u3) / scale + ((u1 / SCALE + u2) / SCALE + u3) / SCALE } } @@ -724,7 +724,7 @@ impl IsaacRng { let mut a = self.a; let mut b = self.b + self.c; - static midpoint: uint = RAND_SIZE as uint / 2; + static MIDPOINT: uint = RAND_SIZE as uint / 2; macro_rules! ind (($x:expr) => { self.mem[($x >> 2) & (RAND_SIZE - 1)] @@ -748,9 +748,9 @@ impl IsaacRng { }} ); - let r = [(0, midpoint), (midpoint, 0)]; + let r = [(0, MIDPOINT), (MIDPOINT, 0)]; for r.iter().advance |&(mr_offset, m2_offset)| { - for uint::range_step(0, midpoint, 4) |base| { + for uint::range_step(0, MIDPOINT, 4) |base| { rngstep!(0, 13); rngstep!(1, -6); rngstep!(2, 2); @@ -830,7 +830,7 @@ pub fn seed() -> ~[u8] { unsafe { let n = rustrt::rand_seed_size() as uint; let mut s = vec::from_elem(n, 0_u8); - do vec::as_mut_buf(s) |p, sz| { + do s.as_mut_buf |p, sz| { rustrt::rand_gen_seed(p, sz as size_t) } s @@ -1087,7 +1087,7 @@ mod tests { for 10.times { unsafe { let seed = super::seed(); - let rt_rng = do vec::as_imm_buf(seed) |p, sz| { + let rt_rng = do seed.as_imm_buf |p, sz| { rustrt::rand_new_seeded(p, sz as size_t) }; let mut rng = IsaacRng::new_seeded(seed); diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs index 16ab4771d0de..9075133b0861 100644 --- a/src/libstd/reflect.rs +++ b/src/libstd/reflect.rs @@ -248,6 +248,14 @@ impl TyVisitor for MovePtrAdaptor { true } + #[cfg(not(stage0))] + fn visit_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.align_to::<~u8>(); + if ! self.inner.visit_uniq_managed(mtbl, inner) { return false; } + self.bump_past::<~u8>(); + true + } + fn visit_ptr(&self, mtbl: uint, inner: *TyDesc) -> bool { self.align_to::<*u8>(); if ! self.inner.visit_ptr(mtbl, inner) { return false; } diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index fdda65d3e95b..dd5075f8e668 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -300,6 +300,15 @@ impl TyVisitor for ReprVisitor { } fn visit_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.writer.write_char('~'); + self.write_mut_qualifier(mtbl); + do self.get::<*c_void> |b| { + self.visit_ptr_inner(*b, inner); + } + } + + #[cfg(not(stage0))] + fn visit_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool { self.writer.write_char('~'); self.write_mut_qualifier(mtbl); do self.get::<&managed::raw::BoxRepr> |b| { diff --git a/src/libstd/rt/global_heap.rs b/src/libstd/rt/global_heap.rs index 4b475d743972..c9bf3b285303 100644 --- a/src/libstd/rt/global_heap.rs +++ b/src/libstd/rt/global_heap.rs @@ -60,12 +60,6 @@ pub unsafe fn realloc_raw(ptr: *mut c_void, size: uint) -> *mut c_void { #[cfg(stage0, not(test))] #[lang="exchange_malloc"] #[inline] -pub unsafe fn exchange_malloc_(td: *c_char, size: uintptr_t) -> *c_char { - exchange_malloc(td, size) -} - -#[cfg(stage0)] -#[inline] pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char { let td = td as *TyDesc; let size = size as uint; @@ -86,13 +80,14 @@ pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char { #[cfg(not(stage0), not(test))] #[lang="exchange_malloc"] #[inline] -pub unsafe fn exchange_malloc_(align: u32, size: uintptr_t) -> *c_char { - exchange_malloc(align, size) +pub unsafe fn exchange_malloc(align: u32, size: uintptr_t) -> *c_char { + malloc_raw(size as uint) as *c_char } -#[cfg(not(stage0))] +#[cfg(not(test))] +#[lang="vector_exchange_malloc"] #[inline] -pub unsafe fn exchange_malloc(align: u32, size: uintptr_t) -> *c_char { +pub unsafe fn vector_exchange_malloc(align: u32, size: uintptr_t) -> *c_char { let total_size = get_box_size(size as uint, align as uint); malloc_raw(total_size as uint) as *c_char } diff --git a/src/libstd/rt/uv/mod.rs b/src/libstd/rt/uv/mod.rs index e39a6384bc63..0eaf0dd3ab64 100644 --- a/src/libstd/rt/uv/mod.rs +++ b/src/libstd/rt/uv/mod.rs @@ -40,6 +40,7 @@ use str::raw::from_c_str; use to_str::ToStr; use ptr::RawPtr; use vec; +use vec::ImmutableVector; use ptr; use str; use libc::{c_void, c_int, size_t, malloc, free}; @@ -312,7 +313,7 @@ pub fn vec_to_uv_buf(v: ~[u8]) -> Buf { unsafe { let data = malloc(v.len() as size_t) as *u8; assert!(data.is_not_null()); - do vec::as_imm_buf(v) |b, l| { + do v.as_imm_buf |b, l| { let data = data as *mut u8; ptr::copy_memory(data, b, l) } diff --git a/src/libstd/run.rs b/src/libstd/run.rs index 9e5def253c7e..7e051b62171c 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -24,7 +24,7 @@ use prelude::*; use ptr; use str; use task; -use vec; +use vec::ImmutableVector; /** * A value representing a child process. @@ -587,7 +587,7 @@ pub fn make_command_line(prog: &str, args: &[~str]) -> ~str { return cmd; fn append_arg(cmd: &mut ~str, arg: &str) { - let quote = arg.iter().any_(|c| c == ' ' || c == '\t'); + let quote = arg.iter().any(|c| c == ' ' || c == '\t'); if quote { cmd.push_char('"'); } @@ -703,7 +703,7 @@ fn with_argv(prog: &str, args: &[~str], argptrs.push(str::as_c_str(*t, |b| b)); } argptrs.push(ptr::null()); - vec::as_imm_buf(argptrs, |buf, _len| cb(buf)) + argptrs.as_imm_buf(|buf, _len| cb(buf)) } #[cfg(unix)] @@ -722,7 +722,7 @@ fn with_envp(env: Option<&[(~str, ~str)]>, cb: &fn(*c_void) -> T) -> T { } ptrs.push(ptr::null()); - vec::as_imm_buf(ptrs, |p, _len| + ptrs.as_imm_buf(|p, _len| unsafe { cb(::cast::transmute(p)) } ) } @@ -743,7 +743,7 @@ fn with_envp(env: Option<&[(~str, ~str)]>, cb: &fn(*mut c_void) -> T) -> T { blk.push_all(kv.as_bytes_with_null_consume()); } blk.push(0); - vec::as_imm_buf(blk, |p, _len| + blk.as_imm_buf(|p, _len| unsafe { cb(::cast::transmute(p)) } ) } diff --git a/src/libstd/std.rs b/src/libstd/std.rs index f0f3bcdd4e96..8f86216d2407 100644 --- a/src/libstd/std.rs +++ b/src/libstd/std.rs @@ -49,7 +49,7 @@ they contained the following prologue: #[link(name = "std", - vers = "0.7", + vers = "0.8-pre", uuid = "c70c24a7-5551-4f73-8e37-380b11d80be8", url = "https://github.com/mozilla/rust/tree/master/src/libstd")]; diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 4115cad65594..3ecafa46a9c9 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -13,8 +13,7 @@ * * Strings are a packed UTF-8 representation of text, stored as null * terminated buffers of u8 bytes. Strings should be indexed in bytes, - * for efficiency, but UTF-8 unsafe operations should be avoided. For - * some heavy-duty uses, try extra::rope. + * for efficiency, but UTF-8 unsafe operations should be avoided. */ use at_vec; @@ -279,7 +278,7 @@ impl CharEq for extern "Rust" fn(char) -> bool { impl<'self, C: CharEq> CharEq for &'self [C] { #[inline] fn matches(&self, c: char) -> bool { - self.iter().any_(|m| m.matches(c)) + self.iter().any(|m| m.matches(c)) } fn only_ascii(&self) -> bool { @@ -602,7 +601,7 @@ pub fn is_utf8(v: &[u8]) -> bool { if i + chsize > total { return false; } i += 1u; while chsize > 1u { - if v[i] & 192u8 != tag_cont_u8 { return false; } + if v[i] & 192u8 != TAG_CONT_U8 { return false; } i += 1u; chsize -= 1u; } @@ -743,18 +742,18 @@ pub struct CharRange { } // UTF-8 tags and ranges -static tag_cont_u8: u8 = 128u8; -static tag_cont: uint = 128u; -static max_one_b: uint = 128u; -static tag_two_b: uint = 192u; -static max_two_b: uint = 2048u; -static tag_three_b: uint = 224u; -static max_three_b: uint = 65536u; -static tag_four_b: uint = 240u; -static max_four_b: uint = 2097152u; -static tag_five_b: uint = 248u; -static max_five_b: uint = 67108864u; -static tag_six_b: uint = 252u; +static TAG_CONT_U8: u8 = 128u8; +static TAG_CONT: uint = 128u; +static MAX_ONE_B: uint = 128u; +static TAG_TWO_B: uint = 192u; +static MAX_TWO_B: uint = 2048u; +static TAG_THREE_B: uint = 224u; +static MAX_THREE_B: uint = 65536u; +static TAG_FOUR_B: uint = 240u; +static MAX_FOUR_B: uint = 2097152u; +static TAG_FIVE_B: uint = 248u; +static MAX_FIVE_B: uint = 67108864u; +static TAG_SIX_B: uint = 252u; /** * A dummy trait to hold all the utility methods that we implement on strings. @@ -826,6 +825,7 @@ pub mod raw { use str::raw; use str::{as_buf, is_utf8}; use vec; + use vec::MutableVector; /// Create a Rust string from a null-terminated *u8 buffer pub unsafe fn from_buf(buf: *u8) -> ~str { @@ -841,7 +841,7 @@ pub mod raw { /// Create a Rust string from a *u8 buffer of the given length pub unsafe fn from_buf_len(buf: *u8, len: uint) -> ~str { let mut v: ~[u8] = vec::with_capacity(len + 1); - vec::as_mut_buf(v, |vbuf, _len| { + v.as_mut_buf(|vbuf, _len| { ptr::copy_memory(vbuf, buf as *u8, len) }); vec::raw::set_len(&mut v, len); @@ -863,7 +863,7 @@ pub mod raw { /// Converts a vector of bytes to a new owned string. pub unsafe fn from_bytes(v: &[u8]) -> ~str { - do vec::as_imm_buf(v) |buf, len| { + do v.as_imm_buf |buf, len| { from_buf_len(buf, len) } } @@ -917,7 +917,7 @@ pub mod raw { assert!((end <= n)); let mut v = vec::with_capacity(end - begin + 1u); - do vec::as_imm_buf(v) |vbuf, _vlen| { + do v.as_imm_buf |vbuf, _vlen| { let vbuf = ::cast::transmute_mut_unsafe(vbuf); let src = ptr::offset(sbuf, begin); ptr::copy_memory(vbuf, src, end - begin); @@ -1728,7 +1728,7 @@ impl<'self> StrSlice<'self> for &'self str { let mut i = i + 1u; while i < end { let byte = self[i]; - assert_eq!(byte & 192u8, tag_cont_u8); + assert_eq!(byte & 192u8, TAG_CONT_U8); val <<= 6u; val += (byte & 63u8) as uint; i += 1u; @@ -1755,7 +1755,7 @@ impl<'self> StrSlice<'self> for &'self str { let mut prev = start; // while there is a previous byte == 10...... - while prev > 0u && self[prev - 1u] & 192u8 == tag_cont_u8 { + while prev > 0u && self[prev - 1u] & 192u8 == TAG_CONT_U8 { prev -= 1u; } @@ -2071,11 +2071,11 @@ impl OwnedStr for ~str { fn push_char(&mut self, c: char) { unsafe { let code = c as uint; - let nb = if code < max_one_b { 1u } - else if code < max_two_b { 2u } - else if code < max_three_b { 3u } - else if code < max_four_b { 4u } - else if code < max_five_b { 5u } + let nb = if code < MAX_ONE_B { 1u } + else if code < MAX_TWO_B { 2u } + else if code < MAX_THREE_B { 3u } + else if code < MAX_FOUR_B { 4u } + else if code < MAX_FIVE_B { 5u } else { 6u }; let len = self.len(); let new_len = len + nb; @@ -2088,34 +2088,34 @@ impl OwnedStr for ~str { *ptr::mut_offset(buf, off) = code as u8; } 2u => { - *ptr::mut_offset(buf, off) = (code >> 6u & 31u | tag_two_b) as u8; - *ptr::mut_offset(buf, off + 1u) = (code & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off) = (code >> 6u & 31u | TAG_TWO_B) as u8; + *ptr::mut_offset(buf, off + 1u) = (code & 63u | TAG_CONT) as u8; } 3u => { - *ptr::mut_offset(buf, off) = (code >> 12u & 15u | tag_three_b) as u8; - *ptr::mut_offset(buf, off + 1u) = (code >> 6u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 2u) = (code & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off) = (code >> 12u & 15u | TAG_THREE_B) as u8; + *ptr::mut_offset(buf, off + 1u) = (code >> 6u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 2u) = (code & 63u | TAG_CONT) as u8; } 4u => { - *ptr::mut_offset(buf, off) = (code >> 18u & 7u | tag_four_b) as u8; - *ptr::mut_offset(buf, off + 1u) = (code >> 12u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 2u) = (code >> 6u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 3u) = (code & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off) = (code >> 18u & 7u | TAG_FOUR_B) as u8; + *ptr::mut_offset(buf, off + 1u) = (code >> 12u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 2u) = (code >> 6u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 3u) = (code & 63u | TAG_CONT) as u8; } 5u => { - *ptr::mut_offset(buf, off) = (code >> 24u & 3u | tag_five_b) as u8; - *ptr::mut_offset(buf, off + 1u) = (code >> 18u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 2u) = (code >> 12u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 3u) = (code >> 6u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 4u) = (code & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off) = (code >> 24u & 3u | TAG_FIVE_B) as u8; + *ptr::mut_offset(buf, off + 1u) = (code >> 18u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 2u) = (code >> 12u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 3u) = (code >> 6u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 4u) = (code & 63u | TAG_CONT) as u8; } 6u => { - *ptr::mut_offset(buf, off) = (code >> 30u & 1u | tag_six_b) as u8; - *ptr::mut_offset(buf, off + 1u) = (code >> 24u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 2u) = (code >> 18u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 3u) = (code >> 12u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 4u) = (code >> 6u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 5u) = (code & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off) = (code >> 30u & 1u | TAG_SIX_B) as u8; + *ptr::mut_offset(buf, off + 1u) = (code >> 24u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 2u) = (code >> 18u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 3u) = (code >> 12u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 4u) = (code >> 6u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 5u) = (code & 63u | TAG_CONT) as u8; } _ => {} } diff --git a/src/libstd/task/local_data_priv.rs b/src/libstd/task/local_data_priv.rs index 0956b76c970a..8dd96df45453 100644 --- a/src/libstd/task/local_data_priv.rs +++ b/src/libstd/task/local_data_priv.rs @@ -142,7 +142,7 @@ unsafe fn local_data_lookup( -> Option<(uint, *libc::c_void)> { let key_value = key_to_key_value(key); - let map_pos = (*map).iter().position_(|entry| + let map_pos = (*map).iter().position(|entry| match *entry { Some((k,_,_)) => k == key_value, None => false @@ -215,7 +215,7 @@ pub unsafe fn local_set( } None => { // Find an empty slot. If not, grow the vector. - match (*map).iter().position_(|x| x.is_none()) { + match (*map).iter().position(|x| x.is_none()) { Some(empty_index) => { map[empty_index] = new_entry; } None => { map.push(new_entry); } } diff --git a/src/libstd/unicode.rs b/src/libstd/unicode.rs index 1e2d5c76feaa..460c0a847c8b 100644 --- a/src/libstd/unicode.rs +++ b/src/libstd/unicode.rs @@ -11,6 +11,7 @@ // The following code was generated by "src/etc/unicode.py" #[allow(missing_doc)]; +#[allow(non_uppercase_statics)]; pub mod general_category { diff --git a/src/libstd/unstable/extfmt.rs b/src/libstd/unstable/extfmt.rs index 624062a7ec40..b1df5175c920 100644 --- a/src/libstd/unstable/extfmt.rs +++ b/src/libstd/unstable/extfmt.rs @@ -472,6 +472,7 @@ pub mod ct { // conditions can be evaluated at compile-time. For now though it's cleaner to // implement it this way, I think. #[doc(hidden)] +#[allow(non_uppercase_statics)] pub mod rt { use float; use str; diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 500143fb5777..ce5ccf2401db 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -91,6 +91,7 @@ pub trait TyVisitor { fn visit_box(&self, mtbl: uint, inner: *TyDesc) -> bool; fn visit_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool; fn visit_ptr(&self, mtbl: uint, inner: *TyDesc) -> bool; fn visit_rptr(&self, mtbl: uint, inner: *TyDesc) -> bool; @@ -417,3 +418,17 @@ pub extern "rust-intrinsic" { pub fn bswap32(x: i32) -> i32; pub fn bswap64(x: i64) -> i64; } + +#[cfg(target_endian = "little")] pub fn to_le16(x: i16) -> i16 { x } +#[cfg(target_endian = "big")] pub fn to_le16(x: i16) -> i16 { unsafe { bswap16(x) } } +#[cfg(target_endian = "little")] pub fn to_le32(x: i32) -> i32 { x } +#[cfg(target_endian = "big")] pub fn to_le32(x: i32) -> i32 { unsafe { bswap32(x) } } +#[cfg(target_endian = "little")] pub fn to_le64(x: i64) -> i64 { x } +#[cfg(target_endian = "big")] pub fn to_le64(x: i64) -> i64 { unsafe { bswap64(x) } } + +#[cfg(target_endian = "little")] pub fn to_be16(x: i16) -> i16 { unsafe { bswap16(x) } } +#[cfg(target_endian = "big")] pub fn to_be16(x: i16) -> i16 { x } +#[cfg(target_endian = "little")] pub fn to_be32(x: i32) -> i32 { unsafe { bswap32(x) } } +#[cfg(target_endian = "big")] pub fn to_be32(x: i32) -> i32 { x } +#[cfg(target_endian = "little")] pub fn to_be64(x: i64) -> i64 { unsafe { bswap64(x) } } +#[cfg(target_endian = "big")] pub fn to_be64(x: i64) -> i64 { x } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 1180ac883e73..2c1e913511ef 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -16,14 +16,12 @@ use cast::transmute; use cast; use container::{Container, Mutable}; use cmp; -use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; +use cmp::{Eq, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; use clone::Clone; use iterator::{FromIterator, Iterator, IteratorUtil}; -use iter::FromIter; use kinds::Copy; use libc::c_void; use num::Zero; -use ops::Add; use option::{None, Option, Some}; use ptr::to_unsafe_ptr; use ptr; @@ -34,9 +32,9 @@ use sys::size_of; use uint; use unstable::intrinsics; #[cfg(stage0)] -use intrinsic::{get_tydesc}; +use intrinsic::{get_tydesc, TyDesc}; #[cfg(not(stage0))] -use unstable::intrinsics::{get_tydesc, contains_managed}; +use unstable::intrinsics::{get_tydesc, contains_managed, TyDesc}; use vec; use util; @@ -56,7 +54,7 @@ pub fn same_length(xs: &[T], ys: &[U]) -> bool { pub fn from_fn(n_elts: uint, op: &fn(uint) -> T) -> ~[T] { unsafe { let mut v = with_capacity(n_elts); - do as_mut_buf(v) |p, _len| { + do v.as_mut_buf |p, _len| { let mut i: uint = 0u; while i < n_elts { intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), op(i)); @@ -81,7 +79,7 @@ pub fn from_elem(n_elts: uint, t: T) -> ~[T] { // vec::with_capacity/ptr::set_memory for primitive types. unsafe { let mut v = with_capacity(n_elts); - do as_mut_buf(v) |p, _len| { + do v.as_mut_buf |p, _len| { let mut i = 0u; while i < n_elts { intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), copy t); @@ -158,165 +156,69 @@ pub fn build_sized_opt(size: Option, build_sized(size.get_or_default(4), builder) } -// Accessors +/// An iterator over the slices of a vector separated by elements that +/// match a predicate function. +pub struct VecSplitIterator<'self, T> { + priv v: &'self [T], + priv n: uint, + priv pred: &'self fn(t: &T) -> bool, + priv finished: bool +} -/// Copies +impl<'self, T> Iterator<&'self [T]> for VecSplitIterator<'self, T> { + fn next(&mut self) -> Option<&'self [T]> { + if self.finished { return None; } -/// Split the vector `v` by applying each element against the predicate `f`. -pub fn split(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { - let ln = v.len(); - if (ln == 0u) { return ~[] } + if self.n == 0 { + self.finished = true; + return Some(self.v); + } - let mut start = 0u; - let mut result = ~[]; - while start < ln { - match v.slice(start, ln).iter().position_(|t| f(t)) { - None => break, - Some(i) => { - result.push(v.slice(start, start + i).to_owned()); - start += i + 1u; + match self.v.iter().position(|x| (self.pred)(x)) { + None => { + self.finished = true; + Some(self.v) + } + Some(idx) => { + let ret = Some(self.v.slice(0, idx)); + self.v = self.v.slice(idx + 1, self.v.len()); + self.n -= 1; + ret } } } - result.push(v.slice(start, ln).to_owned()); - result } -/** - * Split the vector `v` by applying each element against the predicate `f` up - * to `n` times. - */ -pub fn splitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { - let ln = v.len(); - if (ln == 0u) { return ~[] } - - let mut start = 0u; - let mut count = n; - let mut result = ~[]; - while start < ln && count > 0u { - match v.slice(start, ln).iter().position_(|t| f(t)) { - None => break, - Some(i) => { - result.push(v.slice(start, start + i).to_owned()); - // Make sure to skip the separator. - start += i + 1u; - count -= 1u; - } - } - } - result.push(v.slice(start, ln).to_owned()); - result +/// An iterator over the slices of a vector separated by elements that +/// match a predicate function, from back to front. +pub struct VecRSplitIterator<'self, T> { + priv v: &'self [T], + priv n: uint, + priv pred: &'self fn(t: &T) -> bool, + priv finished: bool } -/** - * Reverse split the vector `v` by applying each element against the predicate - * `f`. - */ -pub fn rsplit(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { - let ln = v.len(); - if (ln == 0) { return ~[] } +impl<'self, T> Iterator<&'self [T]> for VecRSplitIterator<'self, T> { + fn next(&mut self) -> Option<&'self [T]> { + if self.finished { return None; } - let mut end = ln; - let mut result = ~[]; - while end > 0 { - match v.slice(0, end).rposition(|t| f(t)) { - None => break, - Some(i) => { - result.push(v.slice(i + 1, end).to_owned()); - end = i; - } - } - } - result.push(v.slice(0u, end).to_owned()); - result.reverse(); - result -} - -/** - * Reverse split the vector `v` by applying each element against the predicate - * `f` up to `n times. - */ -pub fn rsplitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { - let ln = v.len(); - if (ln == 0u) { return ~[] } - - let mut end = ln; - let mut count = n; - let mut result = ~[]; - while end > 0u && count > 0u { - match v.slice(0, end).rposition(|t| f(t)) { - None => break, - Some(i) => { - result.push(v.slice(i + 1u, end).to_owned()); - // Make sure to skip the separator. - end = i; - count -= 1u; - } - } - } - result.push(v.slice(0u, end).to_owned()); - result.reverse(); - result -} - -/// Consumes all elements, in a vector, moving them out into the / closure -/// provided. The vector is traversed from the start to the end. -/// -/// This method does not impose any requirements on the type of the vector being -/// consumed, but it prevents any usage of the vector after this function is -/// called. -/// -/// # Examples -/// -/// ~~~ {.rust} -/// let v = ~[~"a", ~"b"]; -/// do vec::consume(v) |i, s| { -/// // s has type ~str, not &~str -/// io::println(s + fmt!(" %d", i)); -/// } -/// ~~~ -pub fn consume(mut v: ~[T], f: &fn(uint, v: T)) { - unsafe { - do as_mut_buf(v) |p, ln| { - for uint::range(0, ln) |i| { - // NB: This unsafe operation counts on init writing 0s to the - // holes we create in the vector. That ensures that, if the - // iterator fails then we won't try to clean up the consumed - // elements during unwinding - let x = intrinsics::init(); - let p = ptr::mut_offset(p, i); - f(i, ptr::replace_ptr(p, x)); - } + if self.n == 0 { + self.finished = true; + return Some(self.v); } - raw::set_len(&mut v, 0); - } -} - -/// Consumes all elements, in a vector, moving them out into the / closure -/// provided. The vectors is traversed in reverse order (from end to start). -/// -/// This method does not impose any requirements on the type of the vector being -/// consumed, but it prevents any usage of the vector after this function is -/// called. -pub fn consume_reverse(mut v: ~[T], f: &fn(uint, v: T)) { - unsafe { - do as_mut_buf(v) |p, ln| { - let mut i = ln; - while i > 0 { - i -= 1; - - // NB: This unsafe operation counts on init writing 0s to the - // holes we create in the vector. That ensures that, if the - // iterator fails then we won't try to clean up the consumed - // elements during unwinding - let x = intrinsics::init(); - let p = ptr::mut_offset(p, i); - f(i, ptr::replace_ptr(p, x)); + match self.v.rposition(|x| (self.pred)(x)) { + None => { + self.finished = true; + Some(self.v) + } + Some(idx) => { + let ret = Some(self.v.slice(idx + 1, self.v.len())); + self.v = self.v.slice(0, idx); + self.n -= 1; + ret } } - - raw::set_len(&mut v, 0); } } @@ -342,20 +244,6 @@ pub fn append_one(lhs: ~[T], x: T) -> ~[T] { // Functional utilities -/// Consumes a vector, mapping it into a different vector. This function takes -/// ownership of the supplied vector `v`, moving each element into the closure -/// provided to generate a new element. The vector of new elements is then -/// returned. -/// -/// The original vector `v` cannot be used after this function call (it is moved -/// inside), but there are no restrictions on the type of the vector. -pub fn map_consume(v: ~[T], f: &fn(v: T) -> U) -> ~[U] { - let mut result = ~[]; - do consume(v) |_i, x| { - result.push(f(x)); - } - result -} /** * Apply a function to each element of a vector and return a concatenation * of each result vector @@ -366,79 +254,6 @@ pub fn flat_map(v: &[T], f: &fn(t: &T) -> ~[U]) -> ~[U] { result } -pub fn filter_map( - v: ~[T], - f: &fn(t: T) -> Option) -> ~[U] -{ - /*! - * - * Apply a function to each element of a vector and return the results. - * Consumes the input vector. If function `f` returns `None` then that - * element is excluded from the resulting vector. - */ - - let mut result = ~[]; - do consume(v) |_, elem| { - match f(elem) { - None => {} - Some(result_elem) => { result.push(result_elem); } - } - } - result -} - -pub fn filter_mapped( - v: &[T], - f: &fn(t: &T) -> Option) -> ~[U] -{ - /*! - * - * Like `filter_map()`, but operates on a borrowed slice - * and does not consume the input. - */ - - let mut result = ~[]; - for v.iter().advance |elem| { - match f(elem) { - None => {/* no-op */ } - Some(result_elem) => { result.push(result_elem); } - } - } - result -} - -/** - * Construct a new vector from the elements of a vector for which some - * predicate holds. - * - * Apply function `f` to each element of `v` and return a vector containing - * only those elements for which `f` returned true. - */ -pub fn filter(v: ~[T], f: &fn(t: &T) -> bool) -> ~[T] { - let mut result = ~[]; - // FIXME (#4355 maybe): using v.consume here crashes - // do v.consume |_, elem| { - do consume(v) |_, elem| { - if f(&elem) { result.push(elem); } - } - result -} - -/** - * Construct a new vector from the elements of a vector for which some - * predicate holds. - * - * Apply function `f` to each element of `v` and return a vector containing - * only those elements for which `f` returned true. - */ -pub fn filtered(v: &[T], f: &fn(t: &T) -> bool) -> ~[T] { - let mut result = ~[]; - for v.iter().advance |elem| { - if f(elem) { result.push(copy *elem); } - } - result -} - /// Flattens a vector of vectors of T into a single vector of T. pub fn concat(v: &[~[T]]) -> ~[T] { v.concat_vec() } @@ -524,7 +339,7 @@ pub fn unzip_slice(v: &[(T, U)]) -> (~[T], ~[U]) { pub fn unzip(v: ~[(T, U)]) -> (~[T], ~[U]) { let mut ts = ~[]; let mut us = ~[]; - do consume(v) |_i, p| { + for v.consume_iter().advance |p| { let (t, u) = p; ts.push(t); us.push(u); @@ -566,16 +381,6 @@ pub fn zip(mut v: ~[T], mut u: ~[U]) -> ~[(T, U)] { w } -/// Returns a vector with the order of elements reversed -pub fn reversed(v: &[T]) -> ~[T] { - let mut rs: ~[T] = ~[]; - let mut i = v.len(); - if i == 0 { return (rs); } else { i -= 1; } - while i != 0 { rs.push(copy v[i]); i -= 1; } - rs.push(copy v[0]); - rs -} - /** * Iterate over all permutations of vector `v`. * @@ -630,251 +435,222 @@ pub fn each_permutation(values: &[T], fun: &fn(perm : &[T]) -> bool) -> } } -/** - * Iterate over all contiguous windows of length `n` of the vector `v`. - * - * # Example - * - * Print the adjacent pairs of a vector (i.e. `[1,2]`, `[2,3]`, `[3,4]`) - * - * ~~~ {.rust} - * for windowed(2, &[1,2,3,4]) |v| { - * io::println(fmt!("%?", v)); - * } - * ~~~ - * - */ -pub fn windowed<'r, T>(n: uint, v: &'r [T], it: &fn(&'r [T]) -> bool) -> bool { - assert!(1u <= n); - if n > v.len() { return true; } - for uint::range(0, v.len() - n + 1) |i| { - if !it(v.slice(i, i + n)) { return false; } - } - return true; +/// An iterator over the (overlapping) slices of length `size` within +/// a vector. +pub struct VecWindowIter<'self, T> { + priv v: &'self [T], + priv size: uint } -/** - * Work with the buffer of a vector. - * - * Allows for unsafe manipulation of vector contents, which is useful for - * foreign interop. - */ -#[inline] -pub fn as_imm_buf(s: &[T], - /* NB---this CANNOT be const, see below */ - f: &fn(*T, uint) -> U) -> U { - - // NB---Do not change the type of s to `&const [T]`. This is - // unsound. The reason is that we are going to create immutable pointers - // into `s` and pass them to `f()`, but in fact they are potentially - // pointing at *mutable memory*. Use `as_const_buf` or `as_mut_buf` - // instead! - - unsafe { - let v : *(*T,uint) = transmute(&s); - let (buf,len) = *v; - f(buf, len / sys::nonzero_size_of::()) +impl<'self, T> Iterator<&'self [T]> for VecWindowIter<'self, T> { + fn next(&mut self) -> Option<&'self [T]> { + if self.size > self.v.len() { + None + } else { + let ret = Some(self.v.slice(0, self.size)); + self.v = self.v.slice(1, self.v.len()); + ret + } } } -/// Similar to `as_imm_buf` but passing a `*mut T` -#[inline] -pub fn as_mut_buf(s: &mut [T], f: &fn(*mut T, uint) -> U) -> U { - unsafe { - let v : *(*mut T,uint) = transmute(&s); - let (buf,len) = *v; - f(buf, len / sys::nonzero_size_of::()) +/// An iterator over a vector in (non-overlapping) chunks (`size` +/// elements at a time). +pub struct VecChunkIter<'self, T> { + priv v: &'self [T], + priv size: uint +} + +impl<'self, T> Iterator<&'self [T]> for VecChunkIter<'self, T> { + fn next(&mut self) -> Option<&'self [T]> { + if self.size == 0 { + None + } else if self.size >= self.v.len() { + // finished + self.size = 0; + Some(self.v) + } else { + let ret = Some(self.v.slice(0, self.size)); + self.v = self.v.slice(self.size, self.v.len()); + ret + } } } // Equality -/// Tests whether two slices are equal to one another. This is only true if both -/// slices are of the same length, and each of the corresponding elements return -/// true when queried via the `eq` function. -fn eq(a: &[T], b: &[T]) -> bool { - let (a_len, b_len) = (a.len(), b.len()); - if a_len != b_len { return false; } +#[cfg(not(test))] +pub mod traits { + use super::Vector; + use kinds::Copy; + use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Equal, Equiv}; + use ops::Add; - let mut i = 0; - while i < a_len { - if a[i] != b[i] { return false; } - i += 1; + impl<'self,T:Eq> Eq for &'self [T] { + fn eq(&self, other: & &'self [T]) -> bool { + self.len() == other.len() && + self.iter().zip(other.iter()).all(|(s,o)| *s == *o) + } + #[inline] + fn ne(&self, other: & &'self [T]) -> bool { !self.eq(other) } } - true -} -/// Similar to the `vec::eq` function, but this is defined for types which -/// implement `TotalEq` as opposed to types which implement `Eq`. Equality -/// comparisons are done via the `equals` function instead of `eq`. -fn equals(a: &[T], b: &[T]) -> bool { - let (a_len, b_len) = (a.len(), b.len()); - if a_len != b_len { return false; } - - let mut i = 0; - while i < a_len { - if !a[i].equals(&b[i]) { return false; } - i += 1; + impl Eq for ~[T] { + #[inline] + fn eq(&self, other: &~[T]) -> bool { self.as_slice() == *other } + #[inline] + fn ne(&self, other: &~[T]) -> bool { !self.eq(other) } } - true -} -#[cfg(not(test))] -impl<'self,T:Eq> Eq for &'self [T] { - #[inline] - fn eq(&self, other: & &'self [T]) -> bool { eq(*self, *other) } - #[inline] - fn ne(&self, other: & &'self [T]) -> bool { !self.eq(other) } -} + impl Eq for @[T] { + #[inline] + fn eq(&self, other: &@[T]) -> bool { self.as_slice() == *other } + #[inline] + fn ne(&self, other: &@[T]) -> bool { !self.eq(other) } + } -#[cfg(not(test))] -impl Eq for ~[T] { - #[inline] - fn eq(&self, other: &~[T]) -> bool { eq(*self, *other) } - #[inline] - fn ne(&self, other: &~[T]) -> bool { !self.eq(other) } -} - -#[cfg(not(test))] -impl Eq for @[T] { - #[inline] - fn eq(&self, other: &@[T]) -> bool { eq(*self, *other) } - #[inline] - fn ne(&self, other: &@[T]) -> bool { !self.eq(other) } -} - -#[cfg(not(test))] -impl<'self,T:TotalEq> TotalEq for &'self [T] { - #[inline] - fn equals(&self, other: & &'self [T]) -> bool { equals(*self, *other) } -} - -#[cfg(not(test))] -impl TotalEq for ~[T] { - #[inline] - fn equals(&self, other: &~[T]) -> bool { equals(*self, *other) } -} - -#[cfg(not(test))] -impl TotalEq for @[T] { - #[inline] - fn equals(&self, other: &@[T]) -> bool { equals(*self, *other) } -} - -#[cfg(not(test))] -impl<'self,T:Eq> Equiv<~[T]> for &'self [T] { - #[inline] - fn equiv(&self, other: &~[T]) -> bool { eq(*self, *other) } -} - -// Lexicographical comparison - -fn cmp(a: &[T], b: &[T]) -> Ordering { - let low = uint::min(a.len(), b.len()); - - for uint::range(0, low) |idx| { - match a[idx].cmp(&b[idx]) { - Greater => return Greater, - Less => return Less, - Equal => () + impl<'self,T:TotalEq> TotalEq for &'self [T] { + fn equals(&self, other: & &'self [T]) -> bool { + self.len() == other.len() && + self.iter().zip(other.iter()).all(|(s,o)| s.equals(o)) } } - a.len().cmp(&b.len()) -} - -#[cfg(not(test))] -impl<'self,T:TotalOrd> TotalOrd for &'self [T] { - #[inline] - fn cmp(&self, other: & &'self [T]) -> Ordering { cmp(*self, *other) } -} - -#[cfg(not(test))] -impl TotalOrd for ~[T] { - #[inline] - fn cmp(&self, other: &~[T]) -> Ordering { cmp(*self, *other) } -} - -#[cfg(not(test))] -impl TotalOrd for @[T] { - #[inline] - fn cmp(&self, other: &@[T]) -> Ordering { cmp(*self, *other) } -} - -fn lt(a: &[T], b: &[T]) -> bool { - let (a_len, b_len) = (a.len(), b.len()); - let end = uint::min(a_len, b_len); - - let mut i = 0; - while i < end { - let (c_a, c_b) = (&a[i], &b[i]); - if *c_a < *c_b { return true; } - if *c_a > *c_b { return false; } - i += 1; + impl TotalEq for ~[T] { + #[inline] + fn equals(&self, other: &~[T]) -> bool { self.as_slice().equals(&other.as_slice()) } } - a_len < b_len -} - -fn le(a: &[T], b: &[T]) -> bool { !lt(b, a) } -fn ge(a: &[T], b: &[T]) -> bool { !lt(a, b) } -fn gt(a: &[T], b: &[T]) -> bool { lt(b, a) } - -#[cfg(not(test))] -impl<'self,T:Ord> Ord for &'self [T] { - #[inline] - fn lt(&self, other: & &'self [T]) -> bool { lt((*self), (*other)) } - #[inline] - fn le(&self, other: & &'self [T]) -> bool { le((*self), (*other)) } - #[inline] - fn ge(&self, other: & &'self [T]) -> bool { ge((*self), (*other)) } - #[inline] - fn gt(&self, other: & &'self [T]) -> bool { gt((*self), (*other)) } -} - -#[cfg(not(test))] -impl Ord for ~[T] { - #[inline] - fn lt(&self, other: &~[T]) -> bool { lt((*self), (*other)) } - #[inline] - fn le(&self, other: &~[T]) -> bool { le((*self), (*other)) } - #[inline] - fn ge(&self, other: &~[T]) -> bool { ge((*self), (*other)) } - #[inline] - fn gt(&self, other: &~[T]) -> bool { gt((*self), (*other)) } -} - -#[cfg(not(test))] -impl Ord for @[T] { - #[inline] - fn lt(&self, other: &@[T]) -> bool { lt((*self), (*other)) } - #[inline] - fn le(&self, other: &@[T]) -> bool { le((*self), (*other)) } - #[inline] - fn ge(&self, other: &@[T]) -> bool { ge((*self), (*other)) } - #[inline] - fn gt(&self, other: &@[T]) -> bool { gt((*self), (*other)) } -} - -#[cfg(not(test))] -impl<'self,T:Copy> Add<&'self [T], ~[T]> for ~[T] { - #[inline] - fn add(&self, rhs: & &'self [T]) -> ~[T] { - append(copy *self, (*rhs)) + impl TotalEq for @[T] { + #[inline] + fn equals(&self, other: &@[T]) -> bool { self.as_slice().equals(&other.as_slice()) } } + + impl<'self,T:Eq, V: Vector> Equiv for &'self [T] { + #[inline] + fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } + } + + impl<'self,T:Eq, V: Vector> Equiv for ~[T] { + #[inline] + fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } + } + + impl<'self,T:Eq, V: Vector> Equiv for @[T] { + #[inline] + fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } + } + + impl<'self,T:TotalOrd> TotalOrd for &'self [T] { + fn cmp(&self, other: & &'self [T]) -> Ordering { + for self.iter().zip(other.iter()).advance |(s,o)| { + match s.cmp(o) { + Equal => {}, + non_eq => { return non_eq; } + } + } + self.len().cmp(&other.len()) + } + } + + impl TotalOrd for ~[T] { + #[inline] + fn cmp(&self, other: &~[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) } + } + + impl TotalOrd for @[T] { + #[inline] + fn cmp(&self, other: &@[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) } + } + + impl<'self,T:Ord> Ord for &'self [T] { + fn lt(&self, other: & &'self [T]) -> bool { + for self.iter().zip(other.iter()).advance |(s,o)| { + if *s < *o { return true; } + if *s > *o { return false; } + } + self.len() < other.len() + } + #[inline] + fn le(&self, other: & &'self [T]) -> bool { !(*other < *self) } + #[inline] + fn ge(&self, other: & &'self [T]) -> bool { !(*self < *other) } + #[inline] + fn gt(&self, other: & &'self [T]) -> bool { *other < *self } + } + + impl Ord for ~[T] { + #[inline] + fn lt(&self, other: &~[T]) -> bool { self.as_slice() < other.as_slice() } + #[inline] + fn le(&self, other: &~[T]) -> bool { self.as_slice() <= other.as_slice() } + #[inline] + fn ge(&self, other: &~[T]) -> bool { self.as_slice() >= other.as_slice() } + #[inline] + fn gt(&self, other: &~[T]) -> bool { self.as_slice() > other.as_slice() } + } + + impl Ord for @[T] { + #[inline] + fn lt(&self, other: &@[T]) -> bool { self.as_slice() < other.as_slice() } + #[inline] + fn le(&self, other: &@[T]) -> bool { self.as_slice() <= other.as_slice() } + #[inline] + fn ge(&self, other: &@[T]) -> bool { self.as_slice() >= other.as_slice() } + #[inline] + fn gt(&self, other: &@[T]) -> bool { self.as_slice() > other.as_slice() } + } + + impl<'self,T:Copy, V: Vector> Add for &'self [T] { + #[inline] + fn add(&self, rhs: &V) -> ~[T] { + let mut res = self.to_owned(); + res.push_all(rhs.as_slice()); + res + } + } + impl> Add for ~[T] { + #[inline] + fn add(&self, rhs: &V) -> ~[T] { + let mut res = self.to_owned(); + res.push_all(rhs.as_slice()); + res + } + } +} + +#[cfg(test)] +pub mod traits {} + +/// Any vector that can be represented as a slice. +pub trait Vector { + /// Work with `self` as a slice. + fn as_slice<'a>(&'a self) -> &'a [T]; +} +impl<'self,T> Vector for &'self [T] { + #[inline(always)] + fn as_slice<'a>(&'a self) -> &'a [T] { *self } +} +impl Vector for ~[T] { + #[inline(always)] + fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v } +} +impl Vector for @[T] { + #[inline(always)] + fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v } } impl<'self, T> Container for &'self [T] { /// Returns true if a vector contains no elements #[inline] fn is_empty(&self) -> bool { - as_imm_buf(*self, |_p, len| len == 0u) + self.as_imm_buf(|_p, len| len == 0u) } /// Returns the length of a vector #[inline] fn len(&self) -> uint { - as_imm_buf(*self, |_p, len| len) + self.as_imm_buf(|_p, len| len) } } @@ -882,13 +658,13 @@ impl Container for ~[T] { /// Returns true if a vector contains no elements #[inline] fn is_empty(&self) -> bool { - as_imm_buf(*self, |_p, len| len == 0u) + self.as_imm_buf(|_p, len| len == 0u) } /// Returns the length of a vector #[inline] fn len(&self) -> uint { - as_imm_buf(*self, |_p, len| len) + self.as_imm_buf(|_p, len| len) } } @@ -915,6 +691,14 @@ pub trait ImmutableVector<'self, T> { fn slice(&self, start: uint, end: uint) -> &'self [T]; fn iter(self) -> VecIterator<'self, T>; fn rev_iter(self) -> VecRevIterator<'self, T>; + fn split_iter(self, pred: &'self fn(&T) -> bool) -> VecSplitIterator<'self, T>; + fn splitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecSplitIterator<'self, T>; + fn rsplit_iter(self, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T>; + fn rsplitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T>; + + fn window_iter(self, size: uint) -> VecWindowIter<'self, T>; + fn chunk_iter(self, size: uint) -> VecChunkIter<'self, T>; + fn head(&self) -> &'self T; fn head_opt(&self) -> Option<&'self T>; fn tail(&self) -> &'self [T]; @@ -925,12 +709,13 @@ pub trait ImmutableVector<'self, T> { fn last_opt(&self) -> Option<&'self T>; fn rposition(&self, f: &fn(t: &T) -> bool) -> Option; fn flat_map(&self, f: &fn(t: &T) -> ~[U]) -> ~[U]; - fn filter_mapped(&self, f: &fn(t: &T) -> Option) -> ~[U]; unsafe fn unsafe_ref(&self, index: uint) -> *T; fn bsearch(&self, f: &fn(&T) -> Ordering) -> Option; fn map(&self, &fn(t: &T) -> U) -> ~[U]; + + fn as_imm_buf(&self, f: &fn(*T, uint) -> U) -> U; } /// Extension methods for vectors @@ -940,7 +725,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { fn slice(&self, start: uint, end: uint) -> &'self [T] { assert!(start <= end); assert!(end <= self.len()); - do as_imm_buf(*self) |p, _len| { + do self.as_imm_buf |p, _len| { unsafe { transmute((ptr::offset(p, start), (end - start) * sys::nonzero_size_of::())) @@ -966,6 +751,101 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { } } + /// Returns an iterator over the subslices of the vector which are + /// separated by elements that match `pred`. + #[inline] + fn split_iter(self, pred: &'self fn(&T) -> bool) -> VecSplitIterator<'self, T> { + self.splitn_iter(uint::max_value, pred) + } + /// Returns an iterator over the subslices of the vector which are + /// separated by elements that match `pred`, limited to splitting + /// at most `n` times. + #[inline] + fn splitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecSplitIterator<'self, T> { + VecSplitIterator { + v: self, + n: n, + pred: pred, + finished: false + } + } + /// Returns an iterator over the subslices of the vector which are + /// separated by elements that match `pred`. This starts at the + /// end of the vector and works backwards. + #[inline] + fn rsplit_iter(self, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T> { + self.rsplitn_iter(uint::max_value, pred) + } + /// Returns an iterator over the subslices of the vector which are + /// separated by elements that match `pred` limited to splitting + /// at most `n` times. This starts at the end of the vector and + /// works backwards. + #[inline] + fn rsplitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T> { + VecRSplitIterator { + v: self, + n: n, + pred: pred, + finished: false + } + } + + /** + * Returns an iterator over all contiguous windows of length + * `size`. The windows overlap. If the vector is shorter than + * `size`, the iterator returns no values. + * + * # Failure + * + * Fails if `size` is 0. + * + * # Example + * + * Print the adjacent pairs of a vector (i.e. `[1,2]`, `[2,3]`, + * `[3,4]`): + * + * ~~~ {.rust} + * let v = &[1,2,3,4]; + * for v.window_iter().advance |win| { + * io::println(fmt!("%?", win)); + * } + * ~~~ + * + */ + fn window_iter(self, size: uint) -> VecWindowIter<'self, T> { + assert!(size != 0); + VecWindowIter { v: self, size: size } + } + + /** + * + * Returns an iterator over `size` elements of the vector at a + * time. The chunks do not overlap. If `size` does not divide the + * length of the vector, then the last chunk will not have length + * `size`. + * + * # Failure + * + * Fails if `size` is 0. + * + * # Example + * + * Print the vector two elements at a time (i.e. `[1,2]`, + * `[3,4]`, `[5]`): + * + * ~~~ {.rust} + * let v = &[1,2,3,4,5]; + * for v.chunk_iter().advance |win| { + * io::println(fmt!("%?", win)); + * } + * ~~~ + * + */ + fn chunk_iter(self, size: uint) -> VecChunkIter<'self, T> { + assert!(size != 0); + VecChunkIter { v: self, size: size } + } + /// Returns the first element of a vector, failing if the vector is empty. #[inline] fn head(&self) -> &'self T { @@ -1035,17 +915,6 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { fn flat_map(&self, f: &fn(t: &T) -> ~[U]) -> ~[U] { flat_map(*self, f) } - /** - * Apply a function to each element of a vector and return the results - * - * If function `f` returns `none` then that element is excluded from - * the resulting vector. - */ - #[inline] - fn filter_mapped(&self, f: &fn(t: &T) -> Option) -> ~[U] { - filter_mapped(*self, f) - } - /// Returns a pointer to the element at the given index, without doing /// bounds checking. #[inline] @@ -1089,6 +958,28 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { fn map(&self, f: &fn(t: &T) -> U) -> ~[U] { self.iter().transform(f).collect() } + + /** + * Work with the buffer of a vector. + * + * Allows for unsafe manipulation of vector contents, which is useful for + * foreign interop. + */ + #[inline] + fn as_imm_buf(&self, + /* NB---this CANNOT be const, see below */ + f: &fn(*T, uint) -> U) -> U { + // NB---Do not change the type of s to `&const [T]`. This is + // unsound. The reason is that we are going to create immutable pointers + // into `s` and pass them to `f()`, but in fact they are potentially + // pointing at *mutable memory*. Use `as_mut_buf` instead! + + unsafe { + let v : *(*T,uint) = transmute(self); + let (buf,len) = *v; + f(buf, len / sys::nonzero_size_of::()) + } + } } #[allow(missing_doc)] @@ -1102,7 +993,7 @@ impl<'self,T:Eq> ImmutableEqVector for &'self [T] { /// Find the first index containing a matching value #[inline] fn position_elem(&self, x: &T) -> Option { - self.iter().position_(|y| *x == *y) + self.iter().position(|y| *x == *y) } /// Find the last index containing a matching value @@ -1136,25 +1027,12 @@ impl<'self, T: TotalOrd> ImmutableTotalOrdVector for &'self [T] { #[allow(missing_doc)] pub trait ImmutableCopyableVector { - fn filtered(&self, f: &fn(&T) -> bool) -> ~[T]; fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]); unsafe fn unsafe_get(&self, elem: uint) -> T; } /// Extension methods for vectors impl<'self,T:Copy> ImmutableCopyableVector for &'self [T] { - /** - * Construct a new vector from the elements of a vector for which some - * predicate holds. - * - * Apply function `f` to each element of `v` and return a vector - * containing only those elements for which `f` returned true. - */ - #[inline] - fn filtered(&self, f: &fn(t: &T) -> bool) -> ~[T] { - filtered(*self, f) - } - /** * Partitions the vector into those that satisfies the predicate, and * those that do not. @@ -1184,6 +1062,9 @@ impl<'self,T:Copy> ImmutableCopyableVector for &'self [T] { #[allow(missing_doc)] pub trait OwnedVector { + fn consume_iter(self) -> VecConsumeIterator; + fn consume_rev_iter(self) -> VecConsumeRevIterator; + fn reserve(&mut self, n: uint); fn reserve_at_least(&mut self, n: uint); fn capacity(&self) -> uint; @@ -1193,21 +1074,46 @@ pub trait OwnedVector { fn push_all_move(&mut self, rhs: ~[T]); fn pop(&mut self) -> T; + fn pop_opt(&mut self) -> Option; fn shift(&mut self) -> T; + fn shift_opt(&mut self) -> Option; fn unshift(&mut self, x: T); fn insert(&mut self, i: uint, x:T); fn remove(&mut self, i: uint) -> T; fn swap_remove(&mut self, index: uint) -> T; fn truncate(&mut self, newlen: uint); fn retain(&mut self, f: &fn(t: &T) -> bool); - fn consume(self, f: &fn(uint, v: T)); - fn consume_reverse(self, f: &fn(uint, v: T)); - fn filter(self, f: &fn(t: &T) -> bool) -> ~[T]; fn partition(self, f: &fn(&T) -> bool) -> (~[T], ~[T]); fn grow_fn(&mut self, n: uint, op: &fn(uint) -> T); } impl OwnedVector for ~[T] { + /// Creates a consuming iterator, that is, one that moves each + /// value out of the vector (from start to end). The vector cannot + /// be used after calling this. + /// + /// Note that this performs O(n) swaps, and so `consume_rev_iter` + /// (which just calls `pop` repeatedly) is more efficient. + /// + /// # Examples + /// + /// ~~~ {.rust} + /// let v = ~[~"a", ~"b"]; + /// for v.consume_iter().advance |s| { + /// // s has type ~str, not &~str + /// println(s); + /// } + /// ~~~ + fn consume_iter(self) -> VecConsumeIterator { + VecConsumeIterator { v: self, idx: 0 } + } + /// Creates a consuming iterator that moves out of the vector in + /// reverse order. Also see `consume_iter`, however note that this + /// is more efficient. + fn consume_rev_iter(self) -> VecConsumeRevIterator { + VecConsumeRevIterator { v: self } + } + /** * Reserves capacity for exactly `n` elements in the given vector. * @@ -1351,7 +1257,7 @@ impl OwnedVector for ~[T] { let new_len = self.len() + rhs.len(); self.reserve(new_len); unsafe { - do as_mut_buf(rhs) |p, len| { + do rhs.as_mut_buf |p, len| { for uint::range(0, len) |i| { let x = ptr::replace_ptr(ptr::mut_offset(p, i), intrinsics::uninit()); @@ -1362,35 +1268,49 @@ impl OwnedVector for ~[T] { } } - /// Remove the last element from a vector and return it - fn pop(&mut self) -> T { - let ln = self.len(); - if ln == 0 { - fail!("sorry, cannot pop an empty vector") - } - let valptr = ptr::to_mut_unsafe_ptr(&mut self[ln - 1u]); - unsafe { - let val = ptr::replace_ptr(valptr, intrinsics::init()); - raw::set_len(self, ln - 1u); - val + /// Remove the last element from a vector and return it, or `None` if it is empty + fn pop_opt(&mut self) -> Option { + match self.len() { + 0 => None, + ln => { + let valptr = ptr::to_mut_unsafe_ptr(&mut self[ln - 1u]); + unsafe { + let val = ptr::replace_ptr(valptr, intrinsics::init()); + raw::set_len(self, ln - 1u); + Some(val) + } + } } } + + /// Remove the last element from a vector and return it, failing if it is empty + #[inline] + fn pop(&mut self) -> T { + self.pop_opt().expect("pop: empty vector") + } + /// Removes the first element from a vector and return it + #[inline] fn shift(&mut self) -> T { + self.shift_opt().expect("shift: empty vector") + } + + /// Removes the first element from a vector and return it, or `None` if it is empty + fn shift_opt(&mut self) -> Option { unsafe { - assert!(!self.is_empty()); + let ln = match self.len() { + 0 => return None, + 1 => return self.pop_opt(), + 2 => { + let last = self.pop(); + let first = self.pop_opt(); + self.push(last); + return first; + } + x => x + }; - if self.len() == 1 { return self.pop() } - - if self.len() == 2 { - let last = self.pop(); - let first = self.pop(); - self.push(last); - return first; - } - - let ln = self.len(); let next_ln = self.len() - 1; // Save the last element. We're going to overwrite its position @@ -1426,7 +1346,7 @@ impl OwnedVector for ~[T] { let vp = raw::to_mut_ptr(*self); let vp = ptr::mut_offset(vp, next_ln - 1); - ptr::replace_ptr(vp, work_elt) + Some(ptr::replace_ptr(vp, work_elt)) } } @@ -1483,7 +1403,7 @@ impl OwnedVector for ~[T] { /// Shorten a vector, dropping excess elements. fn truncate(&mut self, newlen: uint) { - do as_mut_buf(*self) |p, oldlen| { + do self.as_mut_buf |p, oldlen| { assert!(newlen <= oldlen); unsafe { // This loop is optimized out for non-drop types. @@ -1516,21 +1436,6 @@ impl OwnedVector for ~[T] { } } - #[inline] - fn consume(self, f: &fn(uint, v: T)) { - consume(self, f) - } - - #[inline] - fn consume_reverse(self, f: &fn(uint, v: T)) { - consume_reverse(self, f) - } - - #[inline] - fn filter(self, f: &fn(&T) -> bool) -> ~[T] { - filter(self, f) - } - /** * Partitions the vector into those that satisfies the predicate, and * those that do not. @@ -1540,7 +1445,7 @@ impl OwnedVector for ~[T] { let mut lefts = ~[]; let mut rights = ~[]; - do self.consume |_, elt| { + for self.consume_iter().advance |elt| { if f(&elt) { lefts.push(elt); } else { @@ -1656,7 +1561,7 @@ impl OwnedEqVector for ~[T] { if self.len() == 0 { return; } let mut last_written = 0; let mut next_to_read = 1; - do as_mut_buf(*self) |p, ln| { + do self.as_mut_buf |p, ln| { // last_written < next_to_read <= ln while next_to_read < ln { // last_written < next_to_read < ln @@ -1710,6 +1615,8 @@ pub trait MutableVector<'self, T> { unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T; unsafe fn unsafe_set(&self, index: uint, val: T); + + fn as_mut_buf(&self, f: &fn(*mut T, uint) -> U) -> U; } impl<'self,T> MutableVector<'self, T> for &'self mut [T] { @@ -1718,7 +1625,7 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] { fn mut_slice(self, start: uint, end: uint) -> &'self mut [T] { assert!(start <= end); assert!(end <= self.len()); - do as_mut_buf(self) |p, _len| { + do self.as_mut_buf |p, _len| { unsafe { transmute((ptr::mut_offset(p, start), (end - start) * sys::nonzero_size_of::())) @@ -1791,6 +1698,17 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] { unsafe fn unsafe_set(&self, index: uint, val: T) { *self.unsafe_mut_ref(index) = val; } + + /// Similar to `as_imm_buf` but passing a `*mut T` + #[inline] + fn as_mut_buf(&self, f: &fn(*mut T, uint) -> U) -> U { + unsafe { + let v : *(*mut T,uint) = transmute(self); + let (buf,len) = *v; + f(buf, len / sys::nonzero_size_of::()) + } + } + } /// Trait for ~[T] where T is Cloneable @@ -1840,7 +1758,7 @@ pub mod raw { use ptr; use sys; use unstable::intrinsics; - use vec::{UnboxedVecRepr, as_imm_buf, as_mut_buf, with_capacity}; + use vec::{UnboxedVecRepr, with_capacity, ImmutableVector, MutableVector}; use util; /// The internal representation of a (boxed) vector @@ -1928,7 +1846,7 @@ pub mod raw { */ #[inline] pub unsafe fn get(v: &[T], i: uint) -> T { - as_imm_buf(v, |p, _len| copy *ptr::offset(p, i)) + v.as_imm_buf(|p, _len| copy *ptr::offset(p, i)) } /** @@ -1939,7 +1857,7 @@ pub mod raw { #[inline] pub unsafe fn init_elem(v: &mut [T], i: uint, val: T) { let mut box = Some(val); - do as_mut_buf(v) |p, _len| { + do v.as_mut_buf |p, _len| { let box2 = util::replace(&mut box, None); intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), box2.unwrap()); @@ -1959,7 +1877,7 @@ pub mod raw { pub unsafe fn from_buf_raw(ptr: *T, elts: uint) -> ~[T] { let mut dst = with_capacity(elts); set_len(&mut dst, elts); - as_mut_buf(dst, |p_dst, _len_dst| ptr::copy_memory(p_dst, ptr, elts)); + dst.as_mut_buf(|p_dst, _len_dst| ptr::copy_memory(p_dst, ptr, elts)); dst } @@ -1975,8 +1893,8 @@ pub mod raw { assert!(dst.len() >= count); assert!(src.len() >= count); - do as_mut_buf(dst) |p_dst, _len_dst| { - do as_imm_buf(src) |p_src, _len_src| { + do dst.as_mut_buf |p_dst, _len_dst| { + do src.as_imm_buf |p_src, _len_src| { ptr::copy_memory(p_dst, p_src, count) } } @@ -2000,7 +1918,7 @@ pub mod bytes { impl<'self> MutableByteVector for &'self mut [u8] { #[inline] fn set_memory(self, value: u8) { - do vec::as_mut_buf(self) |p, len| { + do self.as_mut_buf |p, len| { unsafe { ptr::set_memory(p, value, len) }; } } @@ -2107,16 +2025,21 @@ macro_rules! iterator { } #[inline] - fn size_hint(&self) -> (Option, Option) { - let exact = Some(((self.end as uint) - (self.ptr as uint)) / size_of::<$elem>()); - (exact, exact) + fn size_hint(&self) -> (uint, Option) { + let diff = if $step > 0 { + (self.end as uint) - (self.ptr as uint) + } else { + (self.ptr as uint) - (self.end as uint) + }; + let exact = diff / size_of::<$elem>(); + (exact, Some(exact)) } } } } //iterator!{struct VecIterator -> *T, &'self T} -/// An iterator for iterating over a vector +/// An iterator for iterating over a vector. pub struct VecIterator<'self, T> { priv ptr: *T, priv end: *T, @@ -2125,7 +2048,7 @@ pub struct VecIterator<'self, T> { iterator!{impl VecIterator -> &'self T, 1} //iterator!{struct VecRevIterator -> *T, &'self T} -/// An iterator for iterating over a vector in reverse +/// An iterator for iterating over a vector in reverse. pub struct VecRevIterator<'self, T> { priv ptr: *T, priv end: *T, @@ -2134,7 +2057,7 @@ pub struct VecRevIterator<'self, T> { iterator!{impl VecRevIterator -> &'self T, -1} //iterator!{struct VecMutIterator -> *mut T, &'self mut T} -/// An iterator for mutating the elements of a vector +/// An iterator for mutating the elements of a vector. pub struct VecMutIterator<'self, T> { priv ptr: *mut T, priv end: *mut T, @@ -2143,7 +2066,7 @@ pub struct VecMutIterator<'self, T> { iterator!{impl VecMutIterator -> &'self mut T, 1} //iterator!{struct VecMutRevIterator -> *mut T, &'self mut T} -/// An iterator for mutating the elements of a vector in reverse +/// An iterator for mutating the elements of a vector in reverse. pub struct VecMutRevIterator<'self, T> { priv ptr: *mut T, priv end: *mut T, @@ -2151,12 +2074,40 @@ pub struct VecMutRevIterator<'self, T> { } iterator!{impl VecMutRevIterator -> &'self mut T, -1} -impl FromIter for ~[T]{ - #[inline] - pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] { - let mut v = ~[]; - for iter |x| { v.push(x) } - v +/// An iterator that moves out of a vector. +pub struct VecConsumeIterator { + priv v: ~[T], + priv idx: uint, +} + +impl Iterator for VecConsumeIterator { + fn next(&mut self) -> Option { + // this is peculiar, but is required for safety with respect + // to dtors. It traverses the first half of the vec, and + // removes them by swapping them with the last element (and + // popping), which results in the second half in reverse + // order, and so these can just be pop'd off. That is, + // + // [1,2,3,4,5] => 1, [5,2,3,4] => 2, [5,4,3] => 3, [5,4] => 4, + // [5] -> 5, [] + let l = self.v.len(); + if self.idx < l { + self.v.swap(self.idx, l - 1); + self.idx += 1; + } + + self.v.pop_opt() + } +} + +/// An iterator that moves out of a vector in reverse order. +pub struct VecConsumeRevIterator { + priv v: ~[T] +} + +impl Iterator for VecConsumeRevIterator { + fn next(&mut self) -> Option { + self.v.pop_opt() } } @@ -2176,7 +2127,7 @@ impl> FromIterator for ~[A] { impl> FromIterator for ~[A] { pub fn from_iterator(iterator: &mut T) -> ~[A] { let (lower, _) = iterator.size_hint(); - let mut xs = with_capacity(lower.get_or_zero()); + let mut xs = with_capacity(lower); for iterator.advance |x| { xs.push(x); } @@ -2459,6 +2410,17 @@ mod tests { } #[test] + fn test_pop_opt() { + let mut v = ~[5]; + let e = v.pop_opt(); + assert_eq!(v.len(), 0); + assert_eq!(e, Some(5)); + let f = v.pop_opt(); + assert_eq!(f, None); + let g = v.pop_opt(); + assert_eq!(g, None); + } + fn test_swap_remove() { let mut v = ~[1, 2, 3, 4, 5]; let mut e = v.swap_remove(0); @@ -2626,87 +2588,6 @@ mod tests { assert_eq!(w[4], 25u); } - #[test] - fn test_filter_mapped() { - // Test on-stack filter-map. - let mut v = ~[1u, 2u, 3u]; - let mut w = filter_mapped(v, square_if_odd_r); - assert_eq!(w.len(), 2u); - assert_eq!(w[0], 1u); - assert_eq!(w[1], 9u); - - // Test on-heap filter-map. - v = ~[1u, 2u, 3u, 4u, 5u]; - w = filter_mapped(v, square_if_odd_r); - assert_eq!(w.len(), 3u); - assert_eq!(w[0], 1u); - assert_eq!(w[1], 9u); - assert_eq!(w[2], 25u); - - fn halve(i: &int) -> Option { - if *i % 2 == 0 { - Some::(*i / 2) - } else { - None:: - } - } - fn halve_for_sure(i: &int) -> int { *i / 2 } - let all_even: ~[int] = ~[0, 2, 8, 6]; - let all_odd1: ~[int] = ~[1, 7, 3]; - let all_odd2: ~[int] = ~[]; - let mix: ~[int] = ~[9, 2, 6, 7, 1, 0, 0, 3]; - let mix_dest: ~[int] = ~[1, 3, 0, 0]; - assert!(filter_mapped(all_even, halve) == - all_even.map(halve_for_sure)); - assert_eq!(filter_mapped(all_odd1, halve), ~[]); - assert_eq!(filter_mapped(all_odd2, halve), ~[]); - assert_eq!(filter_mapped(mix, halve), mix_dest); - } - - #[test] - fn test_filter_map() { - // Test on-stack filter-map. - let mut v = ~[1u, 2u, 3u]; - let mut w = filter_map(v, square_if_odd_v); - assert_eq!(w.len(), 2u); - assert_eq!(w[0], 1u); - assert_eq!(w[1], 9u); - - // Test on-heap filter-map. - v = ~[1u, 2u, 3u, 4u, 5u]; - w = filter_map(v, square_if_odd_v); - assert_eq!(w.len(), 3u); - assert_eq!(w[0], 1u); - assert_eq!(w[1], 9u); - assert_eq!(w[2], 25u); - - fn halve(i: int) -> Option { - if i % 2 == 0 { - Some::(i / 2) - } else { - None:: - } - } - fn halve_for_sure(i: &int) -> int { *i / 2 } - let all_even: ~[int] = ~[0, 2, 8, 6]; - let all_even0: ~[int] = copy all_even; - let all_odd1: ~[int] = ~[1, 7, 3]; - let all_odd2: ~[int] = ~[]; - let mix: ~[int] = ~[9, 2, 6, 7, 1, 0, 0, 3]; - let mix_dest: ~[int] = ~[1, 3, 0, 0]; - assert!(filter_map(all_even, halve) == - all_even0.map(halve_for_sure)); - assert_eq!(filter_map(all_odd1, halve), ~[]); - assert_eq!(filter_map(all_odd2, halve), ~[]); - assert_eq!(filter_map(mix, halve), mix_dest); - } - - #[test] - fn test_filter() { - assert_eq!(filter(~[1u, 2u, 3u], is_odd), ~[1u, 3u]); - assert_eq!(filter(~[1u, 2u, 4u, 8u, 16u], is_three), ~[]); - } - #[test] fn test_retain() { let mut v = ~[1, 2, 3, 4, 5]; @@ -2821,75 +2702,17 @@ mod tests { } #[test] - fn reverse_and_reversed() { + fn test_reverse() { let mut v: ~[int] = ~[10, 20]; assert_eq!(v[0], 10); assert_eq!(v[1], 20); v.reverse(); assert_eq!(v[0], 20); assert_eq!(v[1], 10); - let v2 = reversed::([10, 20]); - assert_eq!(v2[0], 20); - assert_eq!(v2[1], 10); - v[0] = 30; - assert_eq!(v2[0], 20); - // Make sure they work with 0-length vectors too. - let v4 = reversed::([]); - assert_eq!(v4, ~[]); let mut v3: ~[int] = ~[]; v3.reverse(); - } - - #[test] - fn reversed_mut() { - let v2 = reversed::([10, 20]); - assert_eq!(v2[0], 20); - assert_eq!(v2[1], 10); - } - - #[test] - fn test_split() { - fn f(x: &int) -> bool { *x == 3 } - - assert_eq!(split([], f), ~[]); - assert_eq!(split([1, 2], f), ~[~[1, 2]]); - assert_eq!(split([3, 1, 2], f), ~[~[], ~[1, 2]]); - assert_eq!(split([1, 2, 3], f), ~[~[1, 2], ~[]]); - assert_eq!(split([1, 2, 3, 4, 3, 5], f), ~[~[1, 2], ~[4], ~[5]]); - } - - #[test] - fn test_splitn() { - fn f(x: &int) -> bool { *x == 3 } - - assert_eq!(splitn([], 1u, f), ~[]); - assert_eq!(splitn([1, 2], 1u, f), ~[~[1, 2]]); - assert_eq!(splitn([3, 1, 2], 1u, f), ~[~[], ~[1, 2]]); - assert_eq!(splitn([1, 2, 3], 1u, f), ~[~[1, 2], ~[]]); - assert!(splitn([1, 2, 3, 4, 3, 5], 1u, f) == - ~[~[1, 2], ~[4, 3, 5]]); - } - - #[test] - fn test_rsplit() { - fn f(x: &int) -> bool { *x == 3 } - - assert_eq!(rsplit([], f), ~[]); - assert_eq!(rsplit([1, 2], f), ~[~[1, 2]]); - assert_eq!(rsplit([1, 2, 3], f), ~[~[1, 2], ~[]]); - assert!(rsplit([1, 2, 3, 4, 3, 5], f) == - ~[~[1, 2], ~[4], ~[5]]); - } - - #[test] - fn test_rsplitn() { - fn f(x: &int) -> bool { *x == 3 } - - assert_eq!(rsplitn([], 1u, f), ~[]); - assert_eq!(rsplitn([1, 2], 1u, f), ~[~[1, 2]]); - assert_eq!(rsplitn([1, 2, 3], 1u, f), ~[~[1, 2], ~[]]); - assert_eq!(rsplitn([1, 2, 3, 4, 3, 5], 1u, f), ~[~[1, 2, 3, 4], ~[5]]); + assert!(v3.is_empty()); } #[test] @@ -2933,28 +2756,24 @@ mod tests { } #[test] - fn test_windowed () { - fn t(n: uint, expected: &[&[int]]) { - let mut i = 0; - for windowed(n, [1,2,3,4,5,6]) |v| { - assert_eq!(v, expected[i]); - i += 1; - } - - // check that we actually iterated the right number of times - assert_eq!(i, expected.len()); - } - t(3, &[&[1,2,3],&[2,3,4],&[3,4,5],&[4,5,6]]); - t(4, &[&[1,2,3,4],&[2,3,4,5],&[3,4,5,6]]); - t(7, &[]); - t(8, &[]); + fn test_shift() { + let mut x = ~[1, 2, 3]; + assert_eq!(x.shift(), 1); + assert_eq!(&x, &~[2, 3]); + assert_eq!(x.shift(), 2); + assert_eq!(x.shift(), 3); + assert_eq!(x.len(), 0); } #[test] - #[should_fail] - #[ignore(cfg(windows))] - fn test_windowed_() { - for windowed (0u, [1u,2u,3u,4u,5u,6u]) |_v| {} + fn test_shift_opt() { + let mut x = ~[1, 2, 3]; + assert_eq!(x.shift_opt(), Some(1)); + assert_eq!(&x, &~[2, 3]); + assert_eq!(x.shift_opt(), Some(2)); + assert_eq!(x.shift_opt(), Some(3)); + assert_eq!(x.shift_opt(), None); + assert_eq!(x.len(), 0); } #[test] @@ -3057,156 +2876,6 @@ mod tests { }; } - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_split_fail_ret_true() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do split(v) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - true - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_split_fail_ret_false() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do split(v) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - false - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_splitn_fail_ret_true() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do splitn(v, 100) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - true - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_splitn_fail_ret_false() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do split(v) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - false - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_rsplit_fail_ret_true() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do rsplit(v) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - true - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_rsplit_fail_ret_false() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do rsplit(v) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - false - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_rsplitn_fail_ret_true() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do rsplitn(v, 100) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - true - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_rsplitn_fail_ret_false() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do rsplitn(v, 100) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - false - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - fn test_consume_fail() { - let v = ~[(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do consume(v) |_i, _elt| { - if i == 2 { - fail!() - } - i += 1; - }; - } - #[test] #[ignore(windows)] #[should_fail] @@ -3236,21 +2905,6 @@ mod tests { }; } - #[test] - #[ignore(windows)] - #[should_fail] - fn test_map_consume_fail() { - let v = ~[(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do map_consume(v) |_elt| { - if i == 2 { - fail!() - } - i += 0; - ~[(~0, @0)] - }; - } - #[test] #[ignore(windows)] #[should_fail] @@ -3266,38 +2920,6 @@ mod tests { }; } - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_filter_mapped_fail() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do filter_mapped(v) |_elt| { - if i == 2 { - fail!() - } - i += 0; - Some((~0, @0)) - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_filter_fail() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do v.filtered |_elt| { - if i == 2 { - fail!() - } - i += 0; - true - }; - } - #[test] #[ignore(windows)] #[should_fail] @@ -3333,7 +2955,7 @@ mod tests { #[should_fail] fn test_as_imm_buf_fail() { let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - do as_imm_buf(v) |_buf, _i| { + do v.as_imm_buf |_buf, _i| { fail!() } } @@ -3343,7 +2965,7 @@ mod tests { #[should_fail] fn test_as_mut_buf_fail() { let mut v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - do as_mut_buf(v) |_buf, _i| { + do v.as_mut_buf |_buf, _i| { fail!() } } @@ -3373,20 +2995,30 @@ mod tests { use iterator::*; let xs = [1, 2, 5, 10, 11]; let mut it = xs.iter(); - assert_eq!(it.size_hint(), (Some(5), Some(5))); + assert_eq!(it.size_hint(), (5, Some(5))); assert_eq!(it.next().unwrap(), &1); - assert_eq!(it.size_hint(), (Some(4), Some(4))); + assert_eq!(it.size_hint(), (4, Some(4))); assert_eq!(it.next().unwrap(), &2); - assert_eq!(it.size_hint(), (Some(3), Some(3))); + assert_eq!(it.size_hint(), (3, Some(3))); assert_eq!(it.next().unwrap(), &5); - assert_eq!(it.size_hint(), (Some(2), Some(2))); + assert_eq!(it.size_hint(), (2, Some(2))); assert_eq!(it.next().unwrap(), &10); - assert_eq!(it.size_hint(), (Some(1), Some(1))); + assert_eq!(it.size_hint(), (1, Some(1))); assert_eq!(it.next().unwrap(), &11); - assert_eq!(it.size_hint(), (Some(0), Some(0))); + assert_eq!(it.size_hint(), (0, Some(0))); assert!(it.next().is_none()); } + #[test] + fn test_iter_size_hints() { + use iterator::*; + let mut xs = [1, 2, 5, 10, 11]; + assert_eq!(xs.iter().size_hint(), (5, Some(5))); + assert_eq!(xs.rev_iter().size_hint(), (5, Some(5))); + assert_eq!(xs.mut_iter().size_hint(), (5, Some(5))); + assert_eq!(xs.mut_rev_iter().size_hint(), (5, Some(5))); + } + #[test] fn test_mut_iterator() { use iterator::*; @@ -3421,6 +3053,120 @@ mod tests { assert_eq!(xs, [5, 5, 5, 5, 5]) } + #[test] + fn test_consume_iterator() { + use iterator::*; + let xs = ~[1u,2,3,4,5]; + assert_eq!(xs.consume_iter().fold(0, |a: uint, b: uint| 10*a + b), 12345); + } + + #[test] + fn test_consume_rev_iterator() { + use iterator::*; + let xs = ~[1u,2,3,4,5]; + assert_eq!(xs.consume_rev_iter().fold(0, |a: uint, b: uint| 10*a + b), 54321); + } + + #[test] + fn test_split_iterator() { + let xs = &[1i,2,3,4,5]; + + assert_eq!(xs.split_iter(|x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[1], &[3], &[5]]); + assert_eq!(xs.split_iter(|x| *x == 1).collect::<~[&[int]]>(), + ~[&[], &[2,3,4,5]]); + assert_eq!(xs.split_iter(|x| *x == 5).collect::<~[&[int]]>(), + ~[&[1,2,3,4], &[]]); + assert_eq!(xs.split_iter(|x| *x == 10).collect::<~[&[int]]>(), + ~[&[1,2,3,4,5]]); + assert_eq!(xs.split_iter(|_| true).collect::<~[&[int]]>(), + ~[&[], &[], &[], &[], &[], &[]]); + + let xs: &[int] = &[]; + assert_eq!(xs.split_iter(|x| *x == 5).collect::<~[&[int]]>(), ~[&[]]); + } + + #[test] + fn test_splitn_iterator() { + let xs = &[1i,2,3,4,5]; + + assert_eq!(xs.splitn_iter(0, |x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[1,2,3,4,5]]); + assert_eq!(xs.splitn_iter(1, |x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[1], &[3,4,5]]); + assert_eq!(xs.splitn_iter(3, |_| true).collect::<~[&[int]]>(), + ~[&[], &[], &[], &[4,5]]); + + let xs: &[int] = &[]; + assert_eq!(xs.splitn_iter(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]); + } + + #[test] + fn test_rsplit_iterator() { + let xs = &[1i,2,3,4,5]; + + assert_eq!(xs.rsplit_iter(|x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[5], &[3], &[1]]); + assert_eq!(xs.rsplit_iter(|x| *x == 1).collect::<~[&[int]]>(), + ~[&[2,3,4,5], &[]]); + assert_eq!(xs.rsplit_iter(|x| *x == 5).collect::<~[&[int]]>(), + ~[&[], &[1,2,3,4]]); + assert_eq!(xs.rsplit_iter(|x| *x == 10).collect::<~[&[int]]>(), + ~[&[1,2,3,4,5]]); + + let xs: &[int] = &[]; + assert_eq!(xs.rsplit_iter(|x| *x == 5).collect::<~[&[int]]>(), ~[&[]]); + } + + #[test] + fn test_rsplitn_iterator() { + let xs = &[1,2,3,4,5]; + + assert_eq!(xs.rsplitn_iter(0, |x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[1,2,3,4,5]]); + assert_eq!(xs.rsplitn_iter(1, |x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[5], &[1,2,3]]); + assert_eq!(xs.rsplitn_iter(3, |_| true).collect::<~[&[int]]>(), + ~[&[], &[], &[], &[1,2]]); + + let xs: &[int] = &[]; + assert_eq!(xs.rsplitn_iter(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]); + } + + #[test] + fn test_window_iterator() { + let v = &[1i,2,3,4]; + + assert_eq!(v.window_iter(2).collect::<~[&[int]]>(), ~[&[1,2], &[2,3], &[3,4]]); + assert_eq!(v.window_iter(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[2,3,4]]); + assert!(v.window_iter(6).next().is_none()); + } + + #[test] + #[should_fail] + #[ignore(cfg(windows))] + fn test_window_iterator_0() { + let v = &[1i,2,3,4]; + let _it = v.window_iter(0); + } + + #[test] + fn test_chunk_iterator() { + let v = &[1i,2,3,4,5]; + + assert_eq!(v.chunk_iter(2).collect::<~[&[int]]>(), ~[&[1i,2], &[3,4], &[5]]); + assert_eq!(v.chunk_iter(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[4,5]]); + assert_eq!(v.chunk_iter(6).collect::<~[&[int]]>(), ~[&[1i,2,3,4,5]]); + } + + #[test] + #[should_fail] + #[ignore(cfg(windows))] + fn test_chunk_iterator_0() { + let v = &[1i,2,3,4]; + let _it = v.chunk_iter(0); + } + #[test] fn test_move_from() { let mut a = [1,2,3,4,5]; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 2603cbb2dd7c..8c37c1510cf2 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -109,8 +109,8 @@ pub struct Path { span: span, global: bool, idents: ~[ident], - rp: Option<@Lifetime>, - types: ~[@Ty], + rp: Option, + types: ~[Ty], } pub type crate_num = int; @@ -132,7 +132,7 @@ pub static crate_node_id: node_id = 0; // the "special" built-in traits (see middle::lang_items) and // detects Copy, Send, Send, and Freeze. pub enum TyParamBound { - TraitTyParamBound(@trait_ref), + TraitTyParamBound(trait_ref), RegionTyParamBound } @@ -140,7 +140,7 @@ pub enum TyParamBound { pub struct TyParam { ident: ident, id: node_id, - bounds: @OptVec + bounds: OptVec } #[deriving(Eq, Encodable, Decodable,IterBytes)] @@ -219,7 +219,7 @@ pub type blk = spanned; #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct blk_ { - view_items: ~[@view_item], + view_items: ~[view_item], stmts: ~[@stmt], expr: Option<@expr>, id: node_id, @@ -255,10 +255,10 @@ pub enum pat_ { // which it is. The resolver determines this, and // records this pattern's node_id in an auxiliary // set (of "pat_idents that refer to nullary enums") - pat_ident(binding_mode, @Path, Option<@pat>), - pat_enum(@Path, Option<~[@pat]>), /* "none" means a * pattern where + pat_ident(binding_mode, Path, Option<@pat>), + pat_enum(Path, Option<~[@pat]>), /* "none" means a * pattern where * we don't bind the fields to names */ - pat_struct(@Path, ~[field_pat], bool), + pat_struct(Path, ~[field_pat], bool), pat_tup(~[@pat]), pat_box(@pat), pat_uniq(@pat), @@ -296,7 +296,7 @@ pub enum vstore { vstore_fixed(Option), // [1,2,3,4] vstore_uniq, // ~[1,2,3,4] vstore_box, // @[1,2,3,4] - vstore_slice(Option<@Lifetime>) // &'foo? [1,2,3,4] + vstore_slice(Option) // &'foo? [1,2,3,4] } #[deriving(Eq, Encodable, Decodable,IterBytes)] @@ -361,7 +361,7 @@ pub enum stmt_ { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct local_ { is_mutbl: bool, - ty: @Ty, + ty: Ty, pat: @pat, init: Option<@expr>, id: node_id, @@ -429,12 +429,12 @@ pub enum expr_ { expr_vstore(@expr, expr_vstore), expr_vec(~[@expr], mutability), expr_call(@expr, ~[@expr], CallSugar), - expr_method_call(node_id, @expr, ident, ~[@Ty], ~[@expr], CallSugar), + expr_method_call(node_id, @expr, ident, ~[Ty], ~[@expr], CallSugar), expr_tup(~[@expr]), expr_binary(node_id, binop, @expr, @expr), expr_unary(node_id, unop, @expr), expr_lit(@lit), - expr_cast(@expr, @Ty), + expr_cast(@expr, Ty), expr_if(@expr, blk, Option<@expr>), expr_while(@expr, blk), /* Conditionless loop (can be exited with break, cont, or ret) @@ -454,9 +454,9 @@ pub enum expr_ { expr_copy(@expr), expr_assign(@expr, @expr), expr_assign_op(node_id, binop, @expr, @expr), - expr_field(@expr, ident, ~[@Ty]), + expr_field(@expr, ident, ~[Ty]), expr_index(node_id, @expr, @expr), - expr_path(@Path), + expr_path(Path), /// The special identifier `self`. expr_self, @@ -471,7 +471,7 @@ pub enum expr_ { expr_mac(mac), // A struct literal expression. - expr_struct(@Path, ~[field], Option<@expr>), + expr_struct(Path, ~[field], Option<@expr>), // A vector literal constructed from one repeated element. expr_repeat(@expr /* element */, @expr /* count */, mutability), @@ -583,7 +583,7 @@ pub type mac = spanned; #[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum mac_ { - mac_invoc_tt(@Path,~[token_tree]), // new macro-invocation + mac_invoc_tt(Path,~[token_tree]), // new macro-invocation } pub type lit = spanned; @@ -604,7 +604,7 @@ pub enum lit_ { // type structure in middle/ty.rs as well. #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct mt { - ty: @Ty, + ty: ~Ty, mutbl: mutability, } @@ -701,7 +701,7 @@ impl ToStr for Onceness { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct TyClosure { sigil: Sigil, - region: Option<@Lifetime>, + region: Option, lifetimes: OptVec, purity: purity, onceness: Onceness, @@ -730,11 +730,11 @@ pub enum ty_ { ty_vec(mt), ty_fixed_length_vec(mt, @expr), ty_ptr(mt), - ty_rptr(Option<@Lifetime>, mt), + ty_rptr(Option, mt), ty_closure(@TyClosure), ty_bare_fn(@TyBareFn), - ty_tup(~[@Ty]), - ty_path(@Path, @Option>, node_id), // for #7264; see above + ty_tup(~[Ty]), + ty_path(Path, Option>, node_id), // for #7264; see above ty_mac(mac), // ty_infer means the type should be inferred instead of it having been // specified. This should only appear at the "top level" of a type and not @@ -762,7 +762,7 @@ pub struct inline_asm { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct arg { is_mutbl: bool, - ty: @Ty, + ty: Ty, pat: @pat, id: node_id, } @@ -770,7 +770,7 @@ pub struct arg { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct fn_decl { inputs: ~[arg], - output: @Ty, + output: Ty, cf: ret_style, } @@ -803,7 +803,7 @@ pub enum ret_style { pub enum explicit_self_ { sty_static, // no self sty_value, // `self` - sty_region(Option<@Lifetime>, mutability), // `&'lt self` + sty_region(Option, mutability), // `&'lt self` sty_box(mutability), // `@self` sty_uniq // `~self` } @@ -827,7 +827,7 @@ pub struct method { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct _mod { - view_items: ~[@view_item], + view_items: ~[view_item], items: ~[@item], } @@ -839,13 +839,13 @@ pub enum foreign_mod_sort { named, anonymous } pub struct foreign_mod { sort: foreign_mod_sort, abis: AbiSet, - view_items: ~[@view_item], + view_items: ~[view_item], items: ~[@foreign_item], } #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct variant_arg { - ty: @Ty, + ty: Ty, id: node_id, } @@ -890,13 +890,13 @@ pub enum view_path_ { // or just // // foo::bar::baz (with 'baz =' implicitly on the left) - view_path_simple(ident, @Path, node_id), + view_path_simple(ident, Path, node_id), // foo::bar::* - view_path_glob(@Path, node_id), + view_path_glob(Path, node_id), // foo::bar::{a,b,c} - view_path_list(@Path, ~[path_list_ident], node_id) + view_path_list(Path, ~[path_list_ident], node_id) } #[deriving(Eq, Encodable, Decodable,IterBytes)] @@ -939,7 +939,7 @@ pub struct attribute_ { */ #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct trait_ref { - path: @Path, + path: Path, ref_id: node_id, } @@ -959,7 +959,7 @@ impl visibility { pub struct struct_field_ { kind: struct_field_kind, id: node_id, - ty: @Ty, + ty: Ty, attrs: ~[attribute], } @@ -995,17 +995,17 @@ pub struct item { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum item_ { - item_static(@Ty, mutability, @expr), + item_static(Ty, mutability, @expr), item_fn(fn_decl, purity, AbiSet, Generics, blk), item_mod(_mod), item_foreign_mod(foreign_mod), - item_ty(@Ty, Generics), + item_ty(Ty, Generics), item_enum(enum_def, Generics), item_struct(@struct_def, Generics), - item_trait(Generics, ~[@trait_ref], ~[trait_method]), + item_trait(Generics, ~[trait_ref], ~[trait_method]), item_impl(Generics, - Option<@trait_ref>, // (optional) trait this impl implements - @Ty, // self + Option, // (optional) trait this impl implements + Ty, // self ~[@method]), // a macro invocation (which includes macro definition) item_mac(mac), @@ -1024,7 +1024,7 @@ pub struct foreign_item { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum foreign_item_ { foreign_item_fn(fn_decl, purity, Generics), - foreign_item_static(@Ty, /* is_mutbl */ bool), + foreign_item_static(Ty, /* is_mutbl */ bool), } // The data we save and restore about an inlined item or method. This is not diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 3abbe3970540..59020e9d1837 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -196,7 +196,7 @@ pub fn map_block(b: &blk, (cx,v): (@mut Ctx, visit::vt<@mut Ctx>)) { pub fn map_pat(pat: @pat, (cx,v): (@mut Ctx, visit::vt<@mut Ctx>)) { match pat.node { - pat_ident(_, path, _) => { + pat_ident(_, ref path, _) => { // Note: this is at least *potentially* a pattern... cx.map.insert(pat.id, node_local(ast_util::path_to_ident(path))); } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 529d5bfe70b4..565f181ab859 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -27,7 +27,7 @@ pub fn path_name_i(idents: &[ident]) -> ~str { idents.map(|i| token::interner_get(i.name)).connect("::") } -pub fn path_to_ident(p: @Path) -> ident { copy *p.idents.last() } +pub fn path_to_ident(p: &Path) -> ident { copy *p.idents.last() } pub fn local_def(id: node_id) -> def_id { ast::def_id { crate: local_crate, node: id } @@ -212,8 +212,8 @@ pub fn default_block( } } -pub fn ident_to_path(s: span, i: ident) -> @Path { - @ast::Path { span: s, +pub fn ident_to_path(s: span, i: ident) -> Path { + ast::Path { span: s, global: false, idents: ~[i], rp: None, @@ -238,12 +238,12 @@ pub fn unguarded_pat(a: &arm) -> Option<~[@pat]> { } pub fn public_methods(ms: ~[@method]) -> ~[@method] { - do ms.filtered |m| { + do ms.consume_iter().filter |m| { match m.vis { public => true, _ => false } - } + }.collect() } // extract a ty_method from a trait_method. if the trait_method is @@ -580,7 +580,7 @@ pub fn view_path_id(p: &view_path) -> node_id { /// Returns true if the given struct def is tuple-like; i.e. that its fields /// are unnamed. -pub fn struct_def_is_tuple_like(struct_def: @ast::struct_def) -> bool { +pub fn struct_def_is_tuple_like(struct_def: &ast::struct_def) -> bool { struct_def.ctor_id.is_some() } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index a1a0c7006288..e4532c476d75 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -143,13 +143,13 @@ pub fn get_name_value_str_pair(item: @ast::meta_item) /// Search a list of attributes and return only those with a specific name pub fn find_attrs_by_name(attrs: &[ast::attribute], name: &str) -> ~[ast::attribute] { - do vec::filter_mapped(attrs) |a| { + do attrs.iter().filter_map |a| { if name == get_attr_name(a) { Some(*a) } else { None } - } + }.collect() } /// Search a list of meta items and return only those with a specific name @@ -192,7 +192,7 @@ fn eq(a: @ast::meta_item, b: @ast::meta_item) -> bool { ast::meta_list(ref nb, ref misb) => { if na != nb { return false; } for misa.iter().advance |mi| { - if !misb.iter().any_(|x| x == mi) { return false; } + if !misb.iter().any(|x| x == mi) { return false; } } true } @@ -277,14 +277,7 @@ pub fn sort_meta_items(items: &[@ast::meta_item]) -> ~[@ast::meta_item] { pub fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: &str) -> ~[@ast::meta_item] { - - return vec::filter_mapped(items, |item| { - if name != get_meta_item_name(*item) { - Some(*item) - } else { - None - } - }); + items.consume_iter().filter(|item| name != get_meta_item_name(*item)).collect() } /** diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index bcf617c56ae1..7e89d0407816 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -174,16 +174,11 @@ pub struct FileMapAndBytePos {fm: @FileMap, pos: BytePos} #[deriving(IterBytes)] pub struct NameAndSpan {name: @str, span: Option} -#[deriving(IterBytes)] -pub struct CallInfo { - call_site: span, - callee: NameAndSpan -} - /// Extra information for tracking macro expansion of spans #[deriving(IterBytes)] -pub enum ExpnInfo { - ExpandedFrom(CallInfo) +pub struct ExpnInfo { + call_site: span, + callee: NameAndSpan } pub type FileName = @str; diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index ab7d3fda5013..204028212d62 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -179,10 +179,10 @@ fn diagnosticstr(lvl: level) -> ~str { fn diagnosticcolor(lvl: level) -> term::color::Color { match lvl { - fatal => term::color::bright_red, - error => term::color::bright_red, - warning => term::color::bright_yellow, - note => term::color::bright_green + fatal => term::color::BRIGHT_RED, + error => term::color::BRIGHT_RED, + warning => term::color::BRIGHT_YELLOW, + note => term::color::BRIGHT_GREEN } } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 78fdb99753d4..568688749161 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -11,8 +11,7 @@ use ast; use ast::Name; use codemap; -use codemap::{CodeMap, span, ExpnInfo, ExpandedFrom}; -use codemap::CallInfo; +use codemap::{CodeMap, span, ExpnInfo}; use diagnostic::span_handler; use ext; use parse; @@ -243,7 +242,7 @@ impl ExtCtxt { pub fn cfg(&self) -> ast::crate_cfg { copy self.cfg } pub fn call_site(&self) -> span { match *self.backtrace { - Some(@ExpandedFrom(CallInfo {call_site: cs, _})) => cs, + Some(@ExpnInfo {call_site: cs, _}) => cs, None => self.bug("missing top span") } } @@ -254,21 +253,19 @@ impl ExtCtxt { pub fn mod_path(&self) -> ~[ast::ident] { copy *self.mod_path } pub fn bt_push(&self, ei: codemap::ExpnInfo) { match ei { - ExpandedFrom(CallInfo {call_site: cs, callee: ref callee}) => { + ExpnInfo {call_site: cs, callee: ref callee} => { *self.backtrace = - Some(@ExpandedFrom(CallInfo { + Some(@ExpnInfo { call_site: span {lo: cs.lo, hi: cs.hi, expn_info: *self.backtrace}, - callee: copy *callee})); + callee: copy *callee}); } } } pub fn bt_pop(&self) { match *self.backtrace { - Some(@ExpandedFrom( - CallInfo { - call_site: span {expn_info: prev, _}, _ - })) => { + Some(@ExpnInfo { + call_site: span {expn_info: prev, _}, _}) => { *self.backtrace = prev } _ => self.bug("tried to pop without a push") @@ -329,7 +326,7 @@ pub fn expr_to_ident(cx: @ExtCtxt, expr: @ast::expr, err_msg: &str) -> ast::ident { match expr.node { - ast::expr_path(p) => { + ast::expr_path(ref p) => { if p.types.len() > 0u || p.idents.len() != 1u { cx.span_fatal(expr.span, err_msg); } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 2c1b4cfc5915..73220ec28817 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -32,44 +32,43 @@ mod syntax { pub trait AstBuilder { // paths - fn path(&self, span: span, strs: ~[ast::ident]) -> @ast::Path; - fn path_ident(&self, span: span, id: ast::ident) -> @ast::Path; - fn path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::Path; + fn path(&self, span: span, strs: ~[ast::ident]) -> ast::Path; + fn path_ident(&self, span: span, id: ast::ident) -> ast::Path; + fn path_global(&self, span: span, strs: ~[ast::ident]) -> ast::Path; fn path_all(&self, sp: span, global: bool, idents: ~[ast::ident], - rp: Option<@ast::Lifetime>, - types: ~[@ast::Ty]) - -> @ast::Path; + rp: Option, + types: ~[ast::Ty]) + -> ast::Path; // types - fn ty_mt(&self, ty: @ast::Ty, mutbl: ast::mutability) -> ast::mt; + fn ty_mt(&self, ty: ast::Ty, mutbl: ast::mutability) -> ast::mt; - fn ty(&self, span: span, ty: ast::ty_) -> @ast::Ty; - fn ty_path(&self, @ast::Path, @Option>) -> @ast::Ty; - fn ty_ident(&self, span: span, idents: ast::ident) -> @ast::Ty; + fn ty(&self, span: span, ty: ast::ty_) -> ast::Ty; + fn ty_path(&self, ast::Path, Option>) -> ast::Ty; + fn ty_ident(&self, span: span, idents: ast::ident) -> ast::Ty; fn ty_rptr(&self, span: span, - ty: @ast::Ty, - lifetime: Option<@ast::Lifetime>, - mutbl: ast::mutability) - -> @ast::Ty; - fn ty_uniq(&self, span: span, ty: @ast::Ty) -> @ast::Ty; - fn ty_box(&self, span: span, ty: @ast::Ty, mutbl: ast::mutability) -> @ast::Ty; + ty: ast::Ty, + lifetime: Option, + mutbl: ast::mutability) -> ast::Ty; + fn ty_uniq(&self, span: span, ty: ast::Ty) -> ast::Ty; + fn ty_box(&self, span: span, ty: ast::Ty, mutbl: ast::mutability) -> ast::Ty; - fn ty_option(&self, ty: @ast::Ty) -> @ast::Ty; - fn ty_infer(&self, sp: span) -> @ast::Ty; - fn ty_nil(&self) -> @ast::Ty; + fn ty_option(&self, ty: ast::Ty) -> ast::Ty; + fn ty_infer(&self, sp: span) -> ast::Ty; + fn ty_nil(&self) -> ast::Ty; - fn ty_vars(&self, ty_params: &OptVec) -> ~[@ast::Ty]; - fn ty_vars_global(&self, ty_params: &OptVec) -> ~[@ast::Ty]; - fn ty_field_imm(&self, span: span, name: ident, ty: @ast::Ty) -> ast::ty_field; + fn ty_vars(&self, ty_params: &OptVec) -> ~[ast::Ty]; + fn ty_vars_global(&self, ty_params: &OptVec) -> ~[ast::Ty]; + fn ty_field_imm(&self, span: span, name: ident, ty: ast::Ty) -> ast::ty_field; fn strip_bounds(&self, bounds: &Generics) -> Generics; - fn typaram(&self, id: ast::ident, bounds: @OptVec) -> ast::TyParam; + fn typaram(&self, id: ast::ident, bounds: OptVec) -> ast::TyParam; - fn trait_ref(&self, path: @ast::Path) -> @ast::trait_ref; - fn typarambound(&self, path: @ast::Path) -> ast::TyParamBound; + fn trait_ref(&self, path: ast::Path) -> ast::trait_ref; + fn typarambound(&self, path: ast::Path) -> ast::TyParamBound; fn lifetime(&self, span: span, ident: ast::ident) -> ast::Lifetime; // statements @@ -80,13 +79,13 @@ pub trait AstBuilder { fn blk(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@ast::expr>) -> ast::blk; fn blk_expr(&self, expr: @ast::expr) -> ast::blk; fn blk_all(&self, span: span, - view_items: ~[@ast::view_item], + view_items: ~[ast::view_item], stmts: ~[@ast::stmt], expr: Option<@ast::expr>) -> ast::blk; // expressions fn expr(&self, span: span, node: ast::expr_) -> @ast::expr; - fn expr_path(&self, path: @ast::Path) -> @ast::expr; + fn expr_path(&self, path: ast::Path) -> @ast::expr; fn expr_ident(&self, span: span, id: ast::ident) -> @ast::expr; fn expr_self(&self, span: span) -> @ast::expr; @@ -110,7 +109,7 @@ pub trait AstBuilder { fn expr_blk(&self, b: ast::blk) -> @ast::expr; fn field_imm(&self, span: span, name: ident, e: @ast::expr) -> ast::field; - fn expr_struct(&self, span: span, path: @ast::Path, fields: ~[ast::field]) -> @ast::expr; + fn expr_struct(&self, span: span, path: ast::Path, fields: ~[ast::field]) -> @ast::expr; fn expr_struct_ident(&self, span: span, id: ast::ident, fields: ~[ast::field]) -> @ast::expr; fn expr_lit(&self, sp: span, lit: ast::lit_) -> @ast::expr; @@ -138,9 +137,9 @@ pub trait AstBuilder { span: span, ident: ast::ident, bm: ast::binding_mode) -> @ast::pat; - fn pat_enum(&self, span: span, path: @ast::Path, subpats: ~[@ast::pat]) -> @ast::pat; + fn pat_enum(&self, span: span, path: ast::Path, subpats: ~[@ast::pat]) -> @ast::pat; fn pat_struct(&self, span: span, - path: @ast::Path, field_pats: ~[ast::field_pat]) -> @ast::pat; + path: ast::Path, field_pats: ~[ast::field_pat]) -> @ast::pat; fn arm(&self, span: span, pats: ~[@ast::pat], expr: @ast::expr) -> ast::arm; fn arm_unreachable(&self, span: span) -> ast::arm; @@ -167,25 +166,25 @@ pub trait AstBuilder { fn item(&self, span: span, name: ident, attrs: ~[ast::attribute], node: ast::item_) -> @ast::item; - fn arg(&self, span: span, name: ident, ty: @ast::Ty) -> ast::arg; + fn arg(&self, span: span, name: ident, ty: ast::Ty) -> ast::arg; // XXX unused self - fn fn_decl(&self, inputs: ~[ast::arg], output: @ast::Ty) -> ast::fn_decl; + fn fn_decl(&self, inputs: ~[ast::arg], output: ast::Ty) -> ast::fn_decl; fn item_fn_poly(&self, span: span, name: ident, inputs: ~[ast::arg], - output: @ast::Ty, + output: ast::Ty, generics: Generics, body: ast::blk) -> @ast::item; fn item_fn(&self, span: span, name: ident, inputs: ~[ast::arg], - output: @ast::Ty, + output: ast::Ty, body: ast::blk) -> @ast::item; - fn variant(&self, span: span, name: ident, tys: ~[@ast::Ty]) -> ast::variant; + fn variant(&self, span: span, name: ident, tys: ~[ast::Ty]) -> ast::variant; fn item_enum_poly(&self, span: span, name: ident, @@ -202,14 +201,14 @@ pub trait AstBuilder { fn item_mod(&self, span: span, name: ident, attrs: ~[ast::attribute], - vi: ~[@ast::view_item], items: ~[@ast::item]) -> @ast::item; + vi: ~[ast::view_item], items: ~[@ast::item]) -> @ast::item; fn item_ty_poly(&self, span: span, name: ident, - ty: @ast::Ty, + ty: ast::Ty, generics: Generics) -> @ast::item; - fn item_ty(&self, span: span, name: ident, ty: @ast::Ty) -> @ast::item; + fn item_ty(&self, span: span, name: ident, ty: ast::Ty) -> @ast::item; fn attribute(&self, sp: span, mi: @ast::meta_item) -> ast::attribute; @@ -218,30 +217,30 @@ pub trait AstBuilder { fn meta_name_value(&self, sp: span, name: @str, value: ast::lit_) -> @ast::meta_item; fn view_use(&self, sp: span, - vis: ast::visibility, vp: ~[@ast::view_path]) -> @ast::view_item; + vis: ast::visibility, vp: ~[@ast::view_path]) -> ast::view_item; fn view_use_list(&self, sp: span, vis: ast::visibility, - path: ~[ast::ident], imports: &[ast::ident]) -> @ast::view_item; + path: ~[ast::ident], imports: &[ast::ident]) -> ast::view_item; fn view_use_glob(&self, sp: span, - vis: ast::visibility, path: ~[ast::ident]) -> @ast::view_item; + vis: ast::visibility, path: ~[ast::ident]) -> ast::view_item; } impl AstBuilder for @ExtCtxt { - fn path(&self, span: span, strs: ~[ast::ident]) -> @ast::Path { + fn path(&self, span: span, strs: ~[ast::ident]) -> ast::Path { self.path_all(span, false, strs, None, ~[]) } - fn path_ident(&self, span: span, id: ast::ident) -> @ast::Path { + fn path_ident(&self, span: span, id: ast::ident) -> ast::Path { self.path(span, ~[id]) } - fn path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::Path { + fn path_global(&self, span: span, strs: ~[ast::ident]) -> ast::Path { self.path_all(span, true, strs, None, ~[]) } fn path_all(&self, sp: span, global: bool, idents: ~[ast::ident], - rp: Option<@ast::Lifetime>, - types: ~[@ast::Ty]) - -> @ast::Path { - @ast::Path { + rp: Option, + types: ~[ast::Ty]) + -> ast::Path { + ast::Path { span: sp, global: global, idents: idents, @@ -250,23 +249,23 @@ impl AstBuilder for @ExtCtxt { } } - fn ty_mt(&self, ty: @ast::Ty, mutbl: ast::mutability) -> ast::mt { + fn ty_mt(&self, ty: ast::Ty, mutbl: ast::mutability) -> ast::mt { ast::mt { - ty: ty, + ty: ~ty, mutbl: mutbl } } - fn ty(&self, span: span, ty: ast::ty_) -> @ast::Ty { - @ast::Ty { + fn ty(&self, span: span, ty: ast::ty_) -> ast::Ty { + ast::Ty { id: self.next_id(), span: span, node: ty } } - fn ty_path(&self, path: @ast::Path, bounds: @Option>) - -> @ast::Ty { + fn ty_path(&self, path: ast::Path, bounds: Option>) + -> ast::Ty { self.ty(path.span, ast::ty_path(path, bounds, self.next_id())) } @@ -274,28 +273,28 @@ impl AstBuilder for @ExtCtxt { // Might need to take bounds as an argument in the future, if you ever want // to generate a bounded existential trait type. fn ty_ident(&self, span: span, ident: ast::ident) - -> @ast::Ty { - self.ty_path(self.path_ident(span, ident), @None) + -> ast::Ty { + self.ty_path(self.path_ident(span, ident), None) } fn ty_rptr(&self, span: span, - ty: @ast::Ty, - lifetime: Option<@ast::Lifetime>, + ty: ast::Ty, + lifetime: Option, mutbl: ast::mutability) - -> @ast::Ty { + -> ast::Ty { self.ty(span, ast::ty_rptr(lifetime, self.ty_mt(ty, mutbl))) } - fn ty_uniq(&self, span: span, ty: @ast::Ty) -> @ast::Ty { + fn ty_uniq(&self, span: span, ty: ast::Ty) -> ast::Ty { self.ty(span, ast::ty_uniq(self.ty_mt(ty, ast::m_imm))) } fn ty_box(&self, span: span, - ty: @ast::Ty, mutbl: ast::mutability) -> @ast::Ty { + ty: ast::Ty, mutbl: ast::mutability) -> ast::Ty { self.ty(span, ast::ty_box(self.ty_mt(ty, mutbl))) } - fn ty_option(&self, ty: @ast::Ty) -> @ast::Ty { + fn ty_option(&self, ty: ast::Ty) -> ast::Ty { self.ty_path( self.path_all(dummy_sp(), true, @@ -305,52 +304,50 @@ impl AstBuilder for @ExtCtxt { self.ident_of("Option") ], None, - ~[ ty ]), - @None) + ~[ ty ]), None) } - fn ty_field_imm(&self, span: span, name: ident, ty: @ast::Ty) -> ast::ty_field { + fn ty_field_imm(&self, span: span, name: ident, ty: ast::Ty) -> ast::ty_field { respan(span, ast::ty_field_ { ident: name, - mt: ast::mt { ty: ty, mutbl: ast::m_imm }, + mt: ast::mt { ty: ~ty, mutbl: ast::m_imm }, }) } - fn ty_infer(&self, span: span) -> @ast::Ty { + fn ty_infer(&self, span: span) -> ast::Ty { self.ty(span, ast::ty_infer) } - fn ty_nil(&self) -> @ast::Ty { - @ast::Ty { + fn ty_nil(&self) -> ast::Ty { + ast::Ty { id: self.next_id(), node: ast::ty_nil, span: dummy_sp(), } } - fn typaram(&self, id: ast::ident, bounds: @OptVec) -> ast::TyParam { + fn typaram(&self, id: ast::ident, bounds: OptVec) -> ast::TyParam { ast::TyParam { ident: id, id: self.next_id(), bounds: bounds } } // these are strange, and probably shouldn't be used outside of // pipes. Specifically, the global version possible generates // incorrect code. - fn ty_vars(&self, ty_params: &OptVec) -> ~[@ast::Ty] { + fn ty_vars(&self, ty_params: &OptVec) -> ~[ast::Ty] { opt_vec::take_vec( ty_params.map(|p| self.ty_ident(dummy_sp(), p.ident))) } - fn ty_vars_global(&self, ty_params: &OptVec) -> ~[@ast::Ty] { + fn ty_vars_global(&self, ty_params: &OptVec) -> ~[ast::Ty] { opt_vec::take_vec( ty_params.map(|p| self.ty_path( - self.path_global(dummy_sp(), ~[p.ident]), @None))) + self.path_global(dummy_sp(), ~[p.ident]), None))) } fn strip_bounds(&self, generics: &Generics) -> Generics { - let no_bounds = @opt_vec::Empty; let new_params = do generics.ty_params.map |ty_param| { - ast::TyParam { bounds: no_bounds, ..copy *ty_param } + ast::TyParam { bounds: opt_vec::Empty, ..copy *ty_param } }; Generics { ty_params: new_params, @@ -358,14 +355,14 @@ impl AstBuilder for @ExtCtxt { } } - fn trait_ref(&self, path: @ast::Path) -> @ast::trait_ref { - @ast::trait_ref { + fn trait_ref(&self, path: ast::Path) -> ast::trait_ref { + ast::trait_ref { path: path, ref_id: self.next_id() } } - fn typarambound(&self, path: @ast::Path) -> ast::TyParamBound { + fn typarambound(&self, path: ast::Path) -> ast::TyParamBound { ast::TraitTyParamBound(self.trait_ref(path)) } @@ -400,7 +397,7 @@ impl AstBuilder for @ExtCtxt { } fn blk_all(&self, span: span, - view_items: ~[@ast::view_item], + view_items: ~[ast::view_item], stmts: ~[@ast::stmt], expr: Option<@ast::expr>) -> ast::blk { respan(span, @@ -421,7 +418,7 @@ impl AstBuilder for @ExtCtxt { } } - fn expr_path(&self, path: @ast::Path) -> @ast::expr { + fn expr_path(&self, path: ast::Path) -> @ast::expr { self.expr(path.span, ast::expr_path(path)) } @@ -487,7 +484,7 @@ impl AstBuilder for @ExtCtxt { fn field_imm(&self, span: span, name: ident, e: @ast::expr) -> ast::field { respan(span, ast::field_ { ident: name, expr: e }) } - fn expr_struct(&self, span: span, path: @ast::Path, fields: ~[ast::field]) -> @ast::expr { + fn expr_struct(&self, span: span, path: ast::Path, fields: ~[ast::field]) -> @ast::expr { self.expr(span, ast::expr_struct(path, fields, None)) } fn expr_struct_ident(&self, span: span, @@ -570,12 +567,12 @@ impl AstBuilder for @ExtCtxt { let pat = ast::pat_ident(bm, path, None); self.pat(span, pat) } - fn pat_enum(&self, span: span, path: @ast::Path, subpats: ~[@ast::pat]) -> @ast::pat { + fn pat_enum(&self, span: span, path: ast::Path, subpats: ~[@ast::pat]) -> @ast::pat { let pat = ast::pat_enum(path, Some(subpats)); self.pat(span, pat) } fn pat_struct(&self, span: span, - path: @ast::Path, field_pats: ~[ast::field_pat]) -> @ast::pat { + path: ast::Path, field_pats: ~[ast::field_pat]) -> @ast::pat { let pat = ast::pat_struct(path, field_pats, false); self.pat(span, pat) } @@ -644,7 +641,7 @@ impl AstBuilder for @ExtCtxt { self.lambda1(span, self.blk(span, stmts, None), ident) } - fn arg(&self, span: span, ident: ast::ident, ty: @ast::Ty) -> ast::arg { + fn arg(&self, span: span, ident: ast::ident, ty: ast::Ty) -> ast::arg { let arg_pat = self.pat_ident(span, ident); ast::arg { is_mutbl: false, @@ -655,7 +652,7 @@ impl AstBuilder for @ExtCtxt { } // XXX unused self - fn fn_decl(&self, inputs: ~[ast::arg], output: @ast::Ty) -> ast::fn_decl { + fn fn_decl(&self, inputs: ~[ast::arg], output: ast::Ty) -> ast::fn_decl { ast::fn_decl { inputs: inputs, output: output, @@ -679,7 +676,7 @@ impl AstBuilder for @ExtCtxt { span: span, name: ident, inputs: ~[ast::arg], - output: @ast::Ty, + output: ast::Ty, generics: Generics, body: ast::blk) -> @ast::item { self.item(span, @@ -696,7 +693,7 @@ impl AstBuilder for @ExtCtxt { span: span, name: ident, inputs: ~[ast::arg], - output: @ast::Ty, + output: ast::Ty, body: ast::blk ) -> @ast::item { self.item_fn_poly( @@ -708,10 +705,10 @@ impl AstBuilder for @ExtCtxt { body) } - fn variant(&self, span: span, name: ident, tys: ~[@ast::Ty]) -> ast::variant { - let args = do tys.map |ty| { - ast::variant_arg { ty: *ty, id: self.next_id() } - }; + fn variant(&self, span: span, name: ident, tys: ~[ast::Ty]) -> ast::variant { + let args = tys.consume_iter().transform(|ty| { + ast::variant_arg { ty: ty, id: self.next_id() } + }).collect(); respan(span, ast::variant_ { @@ -762,7 +759,7 @@ impl AstBuilder for @ExtCtxt { fn item_mod(&self, span: span, name: ident, attrs: ~[ast::attribute], - vi: ~[@ast::view_item], + vi: ~[ast::view_item], items: ~[@ast::item]) -> @ast::item { self.item( span, @@ -775,12 +772,12 @@ impl AstBuilder for @ExtCtxt { ) } - fn item_ty_poly(&self, span: span, name: ident, ty: @ast::Ty, + fn item_ty_poly(&self, span: span, name: ident, ty: ast::Ty, generics: Generics) -> @ast::item { self.item(span, name, ~[], ast::item_ty(ty, generics)) } - fn item_ty(&self, span: span, name: ident, ty: @ast::Ty) -> @ast::item { + fn item_ty(&self, span: span, name: ident, ty: ast::Ty) -> @ast::item { self.item_ty_poly(span, name, ty, ast_util::empty_generics()) } @@ -804,8 +801,8 @@ impl AstBuilder for @ExtCtxt { } fn view_use(&self, sp: span, - vis: ast::visibility, vp: ~[@ast::view_path]) -> @ast::view_item { - @ast::view_item { + vis: ast::visibility, vp: ~[@ast::view_path]) -> ast::view_item { + ast::view_item { node: ast::view_item_use(vp), attrs: ~[], vis: vis, @@ -814,7 +811,7 @@ impl AstBuilder for @ExtCtxt { } fn view_use_list(&self, sp: span, vis: ast::visibility, - path: ~[ast::ident], imports: &[ast::ident]) -> @ast::view_item { + path: ~[ast::ident], imports: &[ast::ident]) -> ast::view_item { let imports = do imports.map |id| { respan(sp, ast::path_list_ident_ { name: *id, id: self.next_id() }) }; @@ -827,7 +824,7 @@ impl AstBuilder for @ExtCtxt { } fn view_use_glob(&self, sp: span, - vis: ast::visibility, path: ~[ast::ident]) -> @ast::view_item { + vis: ast::visibility, path: ~[ast::ident]) -> ast::view_item { self.view_use(sp, vis, ~[@respan(sp, ast::view_path_glob(self.path(sp, path), self.next_id()))]) diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs index 7df8874076e0..900668df117e 100644 --- a/src/libsyntax/ext/concat_idents.rs +++ b/src/libsyntax/ext/concat_idents.rs @@ -36,7 +36,7 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) let e = @ast::expr { id: cx.next_id(), node: ast::expr_path( - @ast::Path { + ast::Path { span: sp, global: false, idents: ~[res], diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 0e4fc9d96fa8..01769482d082 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -335,9 +335,9 @@ impl<'self> TraitDef<'self> { cx.typarambound(p.to_path(cx, span, type_ident, generics)) }); // require the current trait - bounds.push(cx.typarambound(trait_path)); + bounds.push(cx.typarambound(copy trait_path)); - trait_generics.ty_params.push(cx.typaram(ty_param.ident, @bounds)); + trait_generics.ty_params.push(cx.typaram(ty_param.ident, bounds)); } // Create the reference to the trait. @@ -351,13 +351,12 @@ impl<'self> TraitDef<'self> { let self_lifetime = if generics.lifetimes.is_empty() { None } else { - Some(@*generics.lifetimes.get(0)) + Some(*generics.lifetimes.get(0)) }; // Create the type of `self`. let self_type = cx.ty_path(cx.path_all(span, false, ~[ type_ident ], self_lifetime, - opt_vec::take_vec(self_ty_params)), - @None); + opt_vec::take_vec(self_ty_params)), None); let doc_attr = cx.attribute( span, @@ -457,7 +456,7 @@ impl<'self> MethodDef<'self> { } fn get_ret_ty(&self, cx: @ExtCtxt, span: span, - generics: &Generics, type_ident: ident) -> @ast::Ty { + generics: &Generics, type_ident: ident) -> ast::Ty { self.ret_ty.to_ty(cx, span, type_ident, generics) } @@ -467,7 +466,7 @@ impl<'self> MethodDef<'self> { fn split_self_nonself_args(&self, cx: @ExtCtxt, span: span, type_ident: ident, generics: &Generics) - -> (ast::explicit_self, ~[@expr], ~[@expr], ~[(ident, @ast::Ty)]) { + -> (ast::explicit_self, ~[@expr], ~[@expr], ~[(ident, ast::Ty)]) { let mut self_args = ~[]; let mut nonself_args = ~[]; @@ -515,7 +514,7 @@ impl<'self> MethodDef<'self> { type_ident: ident, generics: &Generics, explicit_self: ast::explicit_self, - arg_types: ~[(ident, @ast::Ty)], + arg_types: ~[(ident, ast::Ty)], body: @expr) -> @ast::method { // create the generics that aren't for Self let fn_generics = self.generics.to_generics(cx, span, type_ident, generics); @@ -890,7 +889,7 @@ fn summarise_struct(cx: @ExtCtxt, span: span, pub fn create_subpatterns(cx: @ExtCtxt, span: span, - field_paths: ~[@ast::Path], + field_paths: ~[ast::Path], mutbl: ast::mutability) -> ~[@ast::pat] { do field_paths.map |&path| { @@ -941,7 +940,7 @@ fn create_struct_pattern(cx: @ExtCtxt, }; let path = cx.path_ident(span, cx.ident_of(fmt!("%s_%u", prefix, i))); - paths.push(path); + paths.push(copy path); ident_expr.push((opt_id, cx.expr_path(path))); } @@ -987,7 +986,7 @@ fn create_enum_variant_pattern(cx: @ExtCtxt, let path = cx.path_ident(span, cx.ident_of(fmt!("%s_%u", prefix, i))); - paths.push(path); + paths.push(copy path); ident_expr.push((None, cx.expr_path(path))); } diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs index e210853bfb4d..255bc6c98775 100644 --- a/src/libsyntax/ext/deriving/ty.rs +++ b/src/libsyntax/ext/deriving/ty.rs @@ -61,16 +61,15 @@ impl<'self> Path<'self> { span: span, self_ty: ident, self_generics: &Generics) - -> @ast::Ty { - cx.ty_path(self.to_path(cx, span, - self_ty, self_generics), @None) + -> ast::Ty { + cx.ty_path(self.to_path(cx, span, self_ty, self_generics), None) } pub fn to_path(&self, cx: @ExtCtxt, span: span, self_ty: ident, self_generics: &Generics) - -> @ast::Path { + -> ast::Path { let idents = self.path.map(|s| cx.ident_of(*s) ); let lt = mk_lifetime(cx, span, &self.lifetime); let tys = self.params.map(|t| t.to_ty(cx, span, self_ty, self_generics)); @@ -110,9 +109,9 @@ pub fn nil_ty() -> Ty<'static> { Tuple(~[]) } -fn mk_lifetime(cx: @ExtCtxt, span: span, lt: &Option<&str>) -> Option<@ast::Lifetime> { +fn mk_lifetime(cx: @ExtCtxt, span: span, lt: &Option<&str>) -> Option { match *lt { - Some(ref s) => Some(@cx.lifetime(span, cx.ident_of(*s))), + Some(ref s) => Some(cx.lifetime(span, cx.ident_of(*s))), None => None } } @@ -123,7 +122,7 @@ impl<'self> Ty<'self> { span: span, self_ty: ident, self_generics: &Generics) - -> @ast::Ty { + -> ast::Ty { match *self { Ptr(ref ty, ref ptr) => { let raw_ty = ty.to_ty(cx, span, self_ty, self_generics); @@ -142,8 +141,7 @@ impl<'self> Ty<'self> { } Literal(ref p) => { p.to_ty(cx, span, self_ty, self_generics) } Self => { - cx.ty_path(self.to_path(cx, span, self_ty, self_generics), - @None) + cx.ty_path(self.to_path(cx, span, self_ty, self_generics), None) } Tuple(ref fields) => { let ty = if fields.is_empty() { @@ -162,7 +160,7 @@ impl<'self> Ty<'self> { span: span, self_ty: ident, self_generics: &Generics) - -> @ast::Path { + -> ast::Path { match *self { Self => { let self_params = do self_generics.ty_params.map |ty_param| { @@ -171,7 +169,7 @@ impl<'self> Ty<'self> { let lifetime = if self_generics.lifetimes.is_empty() { None } else { - Some(@*self_generics.lifetimes.get(0)) + Some(*self_generics.lifetimes.get(0)) }; cx.path_all(span, false, ~[self_ty], lifetime, @@ -194,7 +192,7 @@ fn mk_ty_param(cx: @ExtCtxt, span: span, name: &str, bounds: &[Path], let path = b.to_path(cx, span, self_ident, self_generics); cx.typarambound(path) }); - cx.typaram(cx.ident_of(name), @bounds) + cx.typaram(cx.ident_of(name), bounds) } fn mk_generics(lifetimes: ~[ast::Lifetime], ty_params: ~[ast::TyParam]) -> Generics { @@ -251,8 +249,7 @@ pub fn get_explicit_self(cx: @ExtCtxt, span: span, self_ptr: &Option) Send => ast::sty_uniq, Managed(mutbl) => ast::sty_box(mutbl), Borrowed(ref lt, mutbl) => { - let lt = lt.map(|s| @cx.lifetime(span, - cx.ident_of(*s))); + let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(*s))); ast::sty_region(lt, mutbl) } }); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 15f915ba4d8d..71e0d49493b8 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -16,7 +16,7 @@ use ast; use ast_util::{new_rename, new_mark, resolve}; use attr; use codemap; -use codemap::{span, CallInfo, ExpandedFrom, NameAndSpan, spanned}; +use codemap::{span, ExpnInfo, NameAndSpan, spanned}; use ext::base::*; use fold::*; use parse; @@ -40,7 +40,7 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv, expr_mac(ref mac) => { match (*mac).node { // Token-tree macros: - mac_invoc_tt(pth, ref tts) => { + mac_invoc_tt(ref pth, ref tts) => { if (pth.idents.len() > 1u) { cx.span_fatal( pth.span, @@ -60,13 +60,13 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv, expander: exp, span: exp_sp }))) => { - cx.bt_push(ExpandedFrom(CallInfo { + cx.bt_push(ExpnInfo { call_site: s, callee: NameAndSpan { name: extnamestr, span: exp_sp, }, - })); + }); let expanded = match exp(cx, mac.span, *tts) { MRExpr(e) => e, @@ -131,13 +131,13 @@ pub fn expand_mod_items(extsbox: @mut SyntaxEnv, match (*extsbox).find(&intern(mname)) { Some(@SE(ItemDecorator(dec_fn))) => { - cx.bt_push(ExpandedFrom(CallInfo { + cx.bt_push(ExpnInfo { call_site: attr.span, callee: NameAndSpan { name: mname, span: None } - })); + }); let r = dec_fn(cx, attr.span, attr.node.value, items); cx.bt_pop(); r @@ -198,7 +198,7 @@ pub fn expand_item(extsbox: @mut SyntaxEnv, // does this attribute list contain "macro_escape" ? pub fn contains_macro_escape (attrs: &[ast::attribute]) -> bool { - attrs.iter().any_(|attr| "macro_escape" == attr::get_attr_name(attr)) + attrs.iter().any(|attr| "macro_escape" == attr::get_attr_name(attr)) } // Support for item-position macro invocations, exactly the same @@ -208,7 +208,7 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv, fld: @ast_fold) -> Option<@ast::item> { let (pth, tts) = match it.node { - item_mac(codemap::spanned { node: mac_invoc_tt(pth, ref tts), _}) => { + item_mac(codemap::spanned { node: mac_invoc_tt(ref pth, ref tts), _}) => { (pth, copy *tts) } _ => cx.span_bug(it.span, "invalid item macro invocation") @@ -227,13 +227,13 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv, given '%s'", extnamestr, ident_to_str(&it.ident))); } - cx.bt_push(ExpandedFrom(CallInfo { + cx.bt_push(ExpnInfo { call_site: it.span, callee: NameAndSpan { name: extnamestr, span: expand.span } - })); + }); ((*expand).expander)(cx, it.span, tts) } Some(@SE(IdentTT(ref expand))) => { @@ -242,13 +242,13 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv, fmt!("macro %s! expects an ident argument", extnamestr)); } - cx.bt_push(ExpandedFrom(CallInfo { + cx.bt_push(ExpnInfo { call_site: it.span, callee: NameAndSpan { name: extnamestr, span: expand.span } - })); + }); ((*expand).expander)(cx, it.span, it.ident, tts) } _ => cx.span_fatal( @@ -298,7 +298,7 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv, let (mac, pth, tts, semi) = match *s { stmt_mac(ref mac, semi) => { match mac.node { - mac_invoc_tt(pth, ref tts) => { + mac_invoc_tt(ref pth, ref tts) => { (copy *mac, pth, copy *tts, semi) } } @@ -319,10 +319,10 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv, Some(@SE(NormalTT( SyntaxExpanderTT{expander: exp, span: exp_sp}))) => { - cx.bt_push(ExpandedFrom(CallInfo { + cx.bt_push(ExpnInfo { call_site: sp, callee: NameAndSpan { name: extnamestr, span: exp_sp } - })); + }); let expanded = match exp(cx, mac.span, tts) { MRExpr(e) => @codemap::spanned { node: stmt_expr(e, cx.next_id()), @@ -372,10 +372,10 @@ pub fn new_name_finder() -> @Visitor<@mut ~[ast::ident]> { (ident_accum, v): (@mut ~[ast::ident], visit::vt<@mut ~[ast::ident]>)| { match *p { // we found a pat_ident! - ast::pat{id:_, node: ast::pat_ident(_,path,ref inner), span:_} => { + ast::pat{id:_, node: ast::pat_ident(_,ref path,ref inner), span:_} => { match path { // a path of length one: - @ast::Path{global: false,idents: [id], span:_,rp:_,types:_} => + &ast::Path{global: false,idents: [id], span:_,rp:_,types:_} => ident_accum.push(id), // I believe these must be enums... _ => () @@ -580,6 +580,7 @@ pub fn core_macros() -> @str { pub mod $c { fn key(_x: @::std::condition::Handler<$in,$out>) { } + #[allow(non_uppercase_statics)] pub static cond : ::std::condition::Condition<'static,$in,$out> = ::std::condition::Condition { @@ -595,6 +596,7 @@ pub fn core_macros() -> @str { pub mod $c { fn key(_x: @::std::condition::Handler<$in,$out>) { } + #[allow(non_uppercase_statics)] pub static cond : ::std::condition::Condition<'static,$in,$out> = ::std::condition::Condition { diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index 76073199f645..333570b6c9d7 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -22,7 +22,6 @@ use ext::build::AstBuilder; use std::option; use std::unstable::extfmt::ct::*; -use std::vec; use parse::token::{str_to_ident}; pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) @@ -268,7 +267,7 @@ fn pieces_to_expr(cx: @ExtCtxt, sp: span, corresponding function in std::unstable::extfmt. Each function takes a buffer to insert data into along with the data being formatted. */ let npieces = pieces.len(); - do vec::consume(pieces) |i, pc| { + for pieces.consume_iter().enumerate().advance |(i, pc)| { match pc { /* Raw strings get appended via str::push_str */ PieceString(s) => { diff --git a/src/libsyntax/ext/log_syntax.rs b/src/libsyntax/ext/log_syntax.rs index 5b789cbc26c1..9e6776363a82 100644 --- a/src/libsyntax/ext/log_syntax.rs +++ b/src/libsyntax/ext/log_syntax.rs @@ -26,7 +26,7 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, cx.print_backtrace(); io::stdout().write_line( print::pprust::tt_to_str( - ast::tt_delim(vec::to_owned(tt)), + &ast::tt_delim(vec::to_owned(tt)), get_ident_interner())); //trivial expression diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs index 1af6e7810a57..a4873e6e34b4 100644 --- a/src/libsyntax/ext/pipes/ast_builder.rs +++ b/src/libsyntax/ext/pipes/ast_builder.rs @@ -25,16 +25,16 @@ mod syntax { pub use parse; } -pub fn path(ids: ~[ident], span: span) -> @ast::Path { - @ast::Path { span: span, +pub fn path(ids: ~[ident], span: span) -> ast::Path { + ast::Path { span: span, global: false, idents: ids, rp: None, types: ~[] } } -pub fn path_global(ids: ~[ident], span: span) -> @ast::Path { - @ast::Path { span: span, +pub fn path_global(ids: ~[ident], span: span) -> ast::Path { + ast::Path { span: span, global: true, idents: ids, rp: None, @@ -42,22 +42,22 @@ pub fn path_global(ids: ~[ident], span: span) -> @ast::Path { } pub trait append_types { - fn add_ty(&self, ty: @ast::Ty) -> @ast::Path; - fn add_tys(&self, tys: ~[@ast::Ty]) -> @ast::Path; + fn add_ty(&self, ty: ast::Ty) -> ast::Path; + fn add_tys(&self, tys: ~[ast::Ty]) -> ast::Path; } -impl append_types for @ast::Path { - fn add_ty(&self, ty: @ast::Ty) -> @ast::Path { - @ast::Path { +impl append_types for ast::Path { + fn add_ty(&self, ty: ast::Ty) -> ast::Path { + ast::Path { types: vec::append_one(copy self.types, ty), - .. copy **self + .. copy *self } } - fn add_tys(&self, tys: ~[@ast::Ty]) -> @ast::Path { - @ast::Path { + fn add_tys(&self, tys: ~[ast::Ty]) -> ast::Path { + ast::Path { types: vec::append(copy self.types, tys), - .. copy **self + .. copy *self } } } diff --git a/src/libsyntax/ext/pipes/check.rs b/src/libsyntax/ext/pipes/check.rs index 8c2898737a35..adf10215cb56 100644 --- a/src/libsyntax/ext/pipes/check.rs +++ b/src/libsyntax/ext/pipes/check.rs @@ -49,7 +49,7 @@ impl proto::visitor<(), (), ()> for @ExtCtxt { } } - fn visit_message(&self, name: @str, _span: span, _tys: &[@ast::Ty], + fn visit_message(&self, name: @str, _span: span, _tys: &[ast::Ty], this: state, next: Option) { match next { Some(ref next_state) => { diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 0e24725ea990..98fc9aa61784 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -25,7 +25,7 @@ use std::vec; pub trait gen_send { fn gen_send(&mut self, cx: @ExtCtxt, try: bool) -> @ast::item; - fn to_ty(&mut self, cx: @ExtCtxt) -> @ast::Ty; + fn to_ty(&mut self, cx: @ExtCtxt) -> ast::Ty; } pub trait to_type_decls { @@ -37,7 +37,7 @@ pub trait to_type_decls { pub trait gen_init { fn gen_init(&self, cx: @ExtCtxt) -> @ast::item; fn compile(&self, cx: @ExtCtxt) -> @ast::item; - fn buffer_ty_path(&self, cx: @ExtCtxt) -> @ast::Ty; + fn buffer_ty_path(&self, cx: @ExtCtxt) -> ast::Ty; fn gen_buffer_type(&self, cx: @ExtCtxt) -> @ast::item; fn gen_buffer_init(&self, ext_cx: @ExtCtxt) -> @ast::expr; fn gen_init_bounded(&self, ext_cx: @ExtCtxt) -> @ast::expr; @@ -56,11 +56,11 @@ impl gen_send for message { next.generics.ty_params.len()); let arg_names = vec::from_fn(tys.len(), |i| cx.ident_of("x_"+i.to_str())); let args_ast: ~[ast::arg] = arg_names.iter().zip(tys.iter()) - .transform(|(n, t)| cx.arg(span, *n, *t)).collect(); + .transform(|(n, t)| cx.arg(span, copy *n, copy *t)).collect(); let pipe_ty = cx.ty_path( path(~[this.data_name()], span) - .add_tys(cx.ty_vars(&this.generics.ty_params)), @None); + .add_tys(cx.ty_vars(&this.generics.ty_params)), None); let args_ast = vec::append( ~[cx.arg(span, cx.ident_of("pipe"), pipe_ty)], args_ast); @@ -117,7 +117,7 @@ impl gen_send for message { let mut rty = cx.ty_path(path(~[next.data_name()], span) - .add_tys(copy next_state.tys), @None); + .add_tys(copy next_state.tys), None); if try { rty = cx.ty_option(rty); } @@ -137,7 +137,7 @@ impl gen_send for message { let arg_names = vec::from_fn(tys.len(), |i| "x_" + i.to_str()); let args_ast: ~[ast::arg] = arg_names.iter().zip(tys.iter()) - .transform(|(n, t)| cx.arg(span, cx.ident_of(*n), *t)).collect(); + .transform(|(&n, t)| cx.arg(span, cx.ident_of(n), copy *t)).collect(); let args_ast = vec::append( ~[cx.arg(span, @@ -145,7 +145,7 @@ impl gen_send for message { cx.ty_path( path(~[this.data_name()], span) .add_tys(cx.ty_vars( - &this.generics.ty_params)), @None))], + &this.generics.ty_params)), None))], args_ast); let message_args = if arg_names.len() == 0 { @@ -189,9 +189,9 @@ impl gen_send for message { } } - fn to_ty(&mut self, cx: @ExtCtxt) -> @ast::Ty { + fn to_ty(&mut self, cx: @ExtCtxt) -> ast::Ty { cx.ty_path(path(~[cx.ident_of(self.name())], self.span()) - .add_tys(cx.ty_vars(&self.get_generics().ty_params)), @None) + .add_tys(cx.ty_vars(&self.get_generics().ty_params)), None) } } @@ -225,7 +225,7 @@ impl to_type_decls for state { cx.ty_path( path(~[cx.ident_of(dir), cx.ident_of(next_name)], span) - .add_tys(copy next_state.tys), @None)) + .add_tys(copy next_state.tys), None)) } None => tys }; @@ -278,8 +278,7 @@ impl to_type_decls for state { self.data_name()], dummy_sp()) .add_tys(cx.ty_vars( - &self.generics.ty_params)), @None)), - @None), + &self.generics.ty_params)), None)), None), cx.strip_bounds(&self.generics))); } else { @@ -298,8 +297,8 @@ impl to_type_decls for state { self.data_name()], dummy_sp()) .add_tys(cx.ty_vars_global( - &self.generics.ty_params)), @None), - self.proto.buffer_ty_path(cx)]), @None), + &self.generics.ty_params)), None), + self.proto.buffer_ty_path(cx)]), None), cx.strip_bounds(&self.generics))); }; items @@ -370,12 +369,12 @@ impl gen_init for protocol { }) } - fn buffer_ty_path(&self, cx: @ExtCtxt) -> @ast::Ty { + fn buffer_ty_path(&self, cx: @ExtCtxt) -> ast::Ty { let mut params: OptVec = opt_vec::Empty; - for (copy self.states).iter().advance |s| { + for self.states.iter().advance |s| { for s.generics.ty_params.iter().advance |tp| { match params.iter().find_(|tpp| tp.ident == tpp.ident) { - None => params.push(*tp), + None => params.push(copy *tp), _ => () } } @@ -384,16 +383,16 @@ impl gen_init for protocol { cx.ty_path(path(~[cx.ident_of("super"), cx.ident_of("__Buffer")], copy self.span) - .add_tys(cx.ty_vars_global(¶ms)), @None) + .add_tys(cx.ty_vars_global(¶ms)), None) } fn gen_buffer_type(&self, cx: @ExtCtxt) -> @ast::item { let ext_cx = cx; let mut params: OptVec = opt_vec::Empty; - let fields = do (copy self.states).iter().transform |s| { + let fields = do self.states.iter().transform |s| { for s.generics.ty_params.iter().advance |tp| { match params.iter().find_(|tpp| tp.ident == tpp.ident) { - None => params.push(*tp), + None => params.push(copy *tp), _ => () } } diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index 0525c6664780..2fe8456c2749 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -37,11 +37,11 @@ impl direction { pub struct next_state { state: @str, - tys: ~[@ast::Ty], + tys: ~[ast::Ty], } // name, span, data, current state, next state -pub struct message(@str, span, ~[@ast::Ty], state, Option); +pub struct message(@str, span, ~[ast::Ty], state, Option); impl message { pub fn name(&mut self) -> @str { @@ -81,7 +81,7 @@ impl state_ { pub fn add_message(@self, name: @str, span: span, - data: ~[@ast::Ty], + data: ~[ast::Ty], next: Option) { self.messages.push(message(name, span, data, self, next)); @@ -96,10 +96,10 @@ impl state_ { } /// Returns the type that is used for the messages. - pub fn to_ty(&self, cx: @ExtCtxt) -> @ast::Ty { + pub fn to_ty(&self, cx: @ExtCtxt) -> ast::Ty { cx.ty_path (path(~[cx.ident_of(self.name)],self.span).add_tys( - cx.ty_vars(&self.generics.ty_params)), @None) + cx.ty_vars(&self.generics.ty_params)), None) } /// Iterate over the states that can be reached in one message @@ -206,7 +206,7 @@ impl protocol_ { pub trait visitor { fn visit_proto(&self, proto: protocol, st: &[Tstate]) -> Tproto; fn visit_state(&self, state: state, m: &[Tmessage]) -> Tstate; - fn visit_message(&self, name: @str, spane: span, tys: &[@ast::Ty], + fn visit_message(&self, name: @str, spane: span, tys: &[ast::Ty], this: state, next: Option) -> Tmessage; } diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index db1902753a38..c550e3382a23 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -88,13 +88,13 @@ pub mod rt { } } - impl ToSource for @ast::Ty { + impl ToSource for ast::Ty { fn to_source(&self) -> @str { - pprust::ty_to_str(*self, get_ident_interner()).to_managed() + pprust::ty_to_str(self, get_ident_interner()).to_managed() } } - impl<'self> ToSource for &'self [@ast::Ty] { + impl<'self> ToSource for &'self [ast::Ty] { fn to_source(&self) -> @str { self.map(|i| i.to_source()).connect(", ").to_managed() } @@ -216,13 +216,13 @@ pub mod rt { } } - impl ToTokens for @ast::Ty { + impl ToTokens for ast::Ty { fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] { cx.parse_tts(self.to_source()) } } - impl<'self> ToTokens for &'self [@ast::Ty] { + impl<'self> ToTokens for &'self [ast::Ty] { fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] { cx.parse_tts(self.to_source()) } diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index f6325c2eb2c1..b43536389e2c 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -10,8 +10,8 @@ use ast; use codemap; -use codemap::{Pos, ExpandedFrom, span}; -use codemap::{CallInfo, NameAndSpan}; +use codemap::{Pos, span}; +use codemap::{ExpnInfo, NameAndSpan}; use ext::base::*; use ext::base; use ext::build::AstBuilder; @@ -117,14 +117,14 @@ pub fn expand_include_bin(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) // recur along an ExpnInfo chain to find the original expression fn topmost_expn_info(expn_info: @codemap::ExpnInfo) -> @codemap::ExpnInfo { match *expn_info { - ExpandedFrom(CallInfo { call_site: ref call_site, _ }) => { + ExpnInfo { call_site: ref call_site, _ } => { match call_site.expn_info { Some(next_expn_info) => { match *next_expn_info { - ExpandedFrom(CallInfo { + ExpnInfo { callee: NameAndSpan { name: ref name, _ }, _ - }) => { + } => { // Don't recurse into file using "include!" if "include" == *name { expn_info diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 80dd0c7247b4..6de504c66fd8 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -82,7 +82,7 @@ pub fn add_new_extension(cx: @ExtCtxt, io::println(fmt!("%s! { %s }", cx.str_of(name), print::pprust::tt_to_str( - ast::tt_delim(vec::to_owned(arg)), + &ast::tt_delim(vec::to_owned(arg)), get_ident_interner()))); } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 4e1451239962..c36b717ea005 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -14,11 +14,9 @@ use codemap::{span, spanned}; use parse::token; use opt_vec::OptVec; -use std::vec; - pub trait ast_fold { fn fold_crate(@self, &crate) -> crate; - fn fold_view_item(@self, @view_item) -> @view_item; + fn fold_view_item(@self, &view_item) -> view_item; fn fold_foreign_item(@self, @foreign_item) -> @foreign_item; fn fold_item(@self, @item) -> Option<@item>; fn fold_struct_field(@self, @struct_field) -> @struct_field; @@ -30,12 +28,12 @@ pub trait ast_fold { fn fold_pat(@self, @pat) -> @pat; fn fold_decl(@self, @decl) -> Option<@decl>; fn fold_expr(@self, @expr) -> @expr; - fn fold_ty(@self, @Ty) -> @Ty; + fn fold_ty(@self, &Ty) -> Ty; fn fold_mod(@self, &_mod) -> _mod; fn fold_foreign_mod(@self, &foreign_mod) -> foreign_mod; fn fold_variant(@self, &variant) -> variant; fn fold_ident(@self, ident) -> ident; - fn fold_path(@self, @Path) -> @Path; + fn fold_path(@self, &Path) -> Path; fn fold_local(@self, @local) -> @local; fn map_exprs(@self, @fn(@expr) -> @expr, &[@expr]) -> ~[@expr]; fn new_id(@self, node_id) -> node_id; @@ -64,7 +62,7 @@ pub struct AstFoldFns { fold_foreign_mod: @fn(&foreign_mod, @ast_fold) -> foreign_mod, fold_variant: @fn(&variant_, span, @ast_fold) -> (variant_, span), fold_ident: @fn(ident, @ast_fold) -> ident, - fold_path: @fn(@Path, @ast_fold) -> Path, + fold_path: @fn(&Path, @ast_fold) -> Path, fold_local: @fn(&local_, span, @ast_fold) -> (local_, span), map_exprs: @fn(@fn(@expr) -> @expr, &[@expr]) -> ~[@expr], new_id: @fn(node_id) -> node_id, @@ -109,7 +107,7 @@ fn fold_attribute_(at: attribute, fld: @ast_fold) -> attribute { fn fold_arg_(a: arg, fld: @ast_fold) -> arg { ast::arg { is_mutbl: a.is_mutbl, - ty: fld.fold_ty(a.ty), + ty: fld.fold_ty(&a.ty), pat: fld.fold_pat(a.pat), id: fld.new_id(a.id), } @@ -119,7 +117,7 @@ fn fold_arg_(a: arg, fld: @ast_fold) -> arg { fn fold_mac_(m: &mac, fld: @ast_fold) -> mac { spanned { node: match m.node { - mac_invoc_tt(p,ref tts) => + mac_invoc_tt(ref p,ref tts) => mac_invoc_tt(fld.fold_path(p), fold_tts(*tts,fld)) }, @@ -156,15 +154,15 @@ fn maybe_fold_ident(t : &token::Token, fld: @ast_fold) -> token::Token { pub fn fold_fn_decl(decl: &ast::fn_decl, fld: @ast_fold) -> ast::fn_decl { ast::fn_decl { - inputs: decl.inputs.map(|x| fold_arg_(*x, fld)), - output: fld.fold_ty(decl.output), + inputs: decl.inputs.map(|x| fold_arg_(/*bad*/ copy *x, fld)), + output: fld.fold_ty(&decl.output), cf: decl.cf, } } fn fold_ty_param_bound(tpb: &TyParamBound, fld: @ast_fold) -> TyParamBound { match *tpb { - TraitTyParamBound(ty) => TraitTyParamBound(fold_trait_ref(ty, fld)), + TraitTyParamBound(ref ty) => TraitTyParamBound(fold_trait_ref(ty, fld)), RegionTyParamBound => RegionTyParamBound } } @@ -173,12 +171,13 @@ pub fn fold_ty_param(tp: TyParam, fld: @ast_fold) -> TyParam { TyParam {ident: tp.ident, id: fld.new_id(tp.id), - bounds: @tp.bounds.map(|x| fold_ty_param_bound(x, fld))} + bounds: tp.bounds.map(|x| fold_ty_param_bound(x, fld))} } pub fn fold_ty_params(tps: &OptVec, fld: @ast_fold) -> OptVec { - tps.map(|tp| fold_ty_param(*tp, fld)) + let tps = /*bad*/ copy *tps; + tps.map_consume(|tp| fold_ty_param(tp, fld)) } pub fn fold_lifetime(l: &Lifetime, @@ -227,14 +226,14 @@ fn noop_fold_foreign_item(ni: @foreign_item, fld: @ast_fold) foreign_item_fn(ref fdec, purity, ref generics) => { foreign_item_fn( ast::fn_decl { - inputs: fdec.inputs.map(|a| fold_arg(*a)), - output: fld.fold_ty(fdec.output), + inputs: fdec.inputs.map(|a| fold_arg(/*bad*/copy *a)), + output: fld.fold_ty(&fdec.output), cf: fdec.cf, }, purity, fold_generics(generics, fld)) } - foreign_item_static(t, m) => { + foreign_item_static(ref t, m) => { foreign_item_static(fld.fold_ty(t), m) } }, @@ -261,14 +260,14 @@ fn noop_fold_struct_field(sf: @struct_field, fld: @ast_fold) @spanned { node: ast::struct_field_ { kind: copy sf.node.kind, id: sf.node.id, - ty: fld.fold_ty(sf.node.ty), + ty: fld.fold_ty(&sf.node.ty), attrs: sf.node.attrs.map(|e| fold_attribute(*e)) }, span: sf.span } } pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ { match *i { - item_static(t, m, e) => item_static(fld.fold_ty(t), m, fld.fold_expr(e)), + item_static(ref t, m, e) => item_static(fld.fold_ty(t), m, fld.fold_expr(e)), item_fn(ref decl, purity, abi, ref generics, ref body) => { item_fn( fold_fn_decl(decl, fld), @@ -282,7 +281,7 @@ pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ { item_foreign_mod(ref nm) => { item_foreign_mod(fld.fold_foreign_mod(nm)) } - item_ty(t, ref generics) => { + item_ty(ref t, ref generics) => { item_ty(fld.fold_ty(t), fold_generics(generics, fld)) } item_enum(ref enum_definition, ref generics) => { @@ -298,10 +297,10 @@ pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ { let struct_def = fold_struct_def(*struct_def, fld); item_struct(struct_def, /* FIXME (#2543) */ copy *generics) } - item_impl(ref generics, ifce, ty, ref methods) => { + item_impl(ref generics, ref ifce, ref ty, ref methods) => { item_impl( fold_generics(generics, fld), - ifce.map(|p| fold_trait_ref(*p, fld)), + ifce.map(|p| fold_trait_ref(p, fld)), fld.fold_ty(ty), methods.map(|x| fld.fold_method(*x)) ) @@ -315,7 +314,7 @@ pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ { }; item_trait( fold_generics(generics, fld), - traits.map(|p| fold_trait_ref(*p, fld)), + traits.map(|p| fold_trait_ref(p, fld)), methods ) } @@ -337,9 +336,9 @@ fn fold_struct_def(struct_def: @ast::struct_def, fld: @ast_fold) } } -fn fold_trait_ref(p: @trait_ref, fld: @ast_fold) -> @trait_ref { - @ast::trait_ref { - path: fld.fold_path(p.path), +fn fold_trait_ref(p: &trait_ref, fld: @ast_fold) -> trait_ref { + ast::trait_ref { + path: fld.fold_path(&p.path), ref_id: fld.new_id(p.ref_id), } } @@ -349,7 +348,7 @@ fn fold_struct_field(f: @struct_field, fld: @ast_fold) -> @struct_field { node: ast::struct_field_ { kind: copy f.node.kind, id: fld.new_id(f.node.id), - ty: fld.fold_ty(f.node.ty), + ty: fld.fold_ty(&f.node.ty), attrs: /* FIXME (#2543) */ copy f.node.attrs, }, span: fld.new_span(f.span), @@ -374,7 +373,7 @@ fn noop_fold_method(m: @method, fld: @ast_fold) -> @method { pub fn noop_fold_block(b: &blk_, fld: @ast_fold) -> blk_ { - let view_items = b.view_items.map(|x| fld.fold_view_item(*x)); + let view_items = b.view_items.map(|x| fld.fold_view_item(x)); let mut stmts = ~[]; for b.stmts.iter().advance |stmt| { match fld.fold_stmt(*stmt) { @@ -421,7 +420,7 @@ fn noop_fold_arm(a: &arm, fld: @ast_fold) -> arm { pub fn noop_fold_pat(p: &pat_, fld: @ast_fold) -> pat_ { match *p { pat_wild => pat_wild, - pat_ident(binding_mode, pth, ref sub) => { + pat_ident(binding_mode, ref pth, ref sub) => { pat_ident( binding_mode, fld.fold_path(pth), @@ -429,13 +428,13 @@ pub fn noop_fold_pat(p: &pat_, fld: @ast_fold) -> pat_ { ) } pat_lit(e) => pat_lit(fld.fold_expr(e)), - pat_enum(pth, ref pats) => { + pat_enum(ref pth, ref pats) => { pat_enum( fld.fold_path(pth), pats.map(|pats| pats.map(|x| fld.fold_pat(*x))) ) } - pat_struct(pth, ref fields, etc) => { + pat_struct(ref pth, ref fields, etc) => { let pth_ = fld.fold_path(pth); let fs = do fields.map |f| { ast::field_pat { @@ -519,7 +518,7 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ { fld.new_id(callee_id), fld.fold_expr(f), fld.fold_ident(i), - tps.map(|x| fld.fold_ty(*x)), + tps.map(|x| fld.fold_ty(x)), fld.map_exprs(|x| fld.fold_expr(x), *args), blk ) @@ -542,7 +541,7 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ { expr_loop_body(f) => expr_loop_body(fld.fold_expr(f)), expr_do_body(f) => expr_do_body(fld.fold_expr(f)), expr_lit(_) => copy *e, - expr_cast(expr, ty) => expr_cast(fld.fold_expr(expr), ty), + expr_cast(expr, ref ty) => expr_cast(fld.fold_expr(expr), copy *ty), expr_addr_of(m, ohs) => expr_addr_of(m, fld.fold_expr(ohs)), expr_if(cond, ref tr, fl) => { expr_if( @@ -588,7 +587,7 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ { expr_field(el, id, ref tys) => { expr_field( fld.fold_expr(el), fld.fold_ident(id), - tys.map(|x| fld.fold_ty(*x)) + tys.map(|x| fld.fold_ty(x)) ) } expr_index(callee_id, el, er) => { @@ -598,7 +597,7 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ { fld.fold_expr(er) ) } - expr_path(pth) => expr_path(fld.fold_path(pth)), + expr_path(ref pth) => expr_path(fld.fold_path(pth)), expr_self => expr_self, expr_break(ref opt_ident) => { expr_break(opt_ident.map(|x| fld.fold_ident(*x))) @@ -623,7 +622,7 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ { }) } expr_mac(ref mac) => expr_mac(fold_mac(mac)), - expr_struct(path, ref fields, maybe_expr) => { + expr_struct(ref path, ref fields, maybe_expr) => { expr_struct( fld.fold_path(path), fields.map(|x| fold_field(*x)), @@ -638,7 +637,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { let fold_mac = |x| fold_mac_(x, fld); fn fold_mt(mt: &mt, fld: @ast_fold) -> mt { mt { - ty: fld.fold_ty(mt.ty), + ty: ~fld.fold_ty(mt.ty), mutbl: mt.mutbl, } } @@ -683,9 +682,9 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { decl: fold_fn_decl(&f.decl, fld) }) } - ty_tup(ref tys) => ty_tup(tys.map(|ty| fld.fold_ty(*ty))), - ty_path(path, bounds, id) => - ty_path(fld.fold_path(path), @fold_opt_bounds(bounds, fld), fld.new_id(id)), + ty_tup(ref tys) => ty_tup(tys.map(|ty| fld.fold_ty(ty))), + ty_path(ref path, ref bounds, id) => + ty_path(fld.fold_path(path), fold_opt_bounds(bounds, fld), fld.new_id(id)), ty_fixed_length_vec(ref mt, e) => { ty_fixed_length_vec( fold_mt(mt, fld), @@ -699,8 +698,8 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { // ...nor do modules pub fn noop_fold_mod(m: &_mod, fld: @ast_fold) -> _mod { ast::_mod { - view_items: m.view_items.iter().transform(|x| fld.fold_view_item(*x)).collect(), - items: vec::filter_mapped(m.items, |x| fld.fold_item(*x)), + view_items: m.view_items.iter().transform(|x| fld.fold_view_item(x)).collect(), + items: m.items.iter().filter_map(|x| fld.fold_item(*x)).collect(), } } @@ -708,14 +707,14 @@ fn noop_fold_foreign_mod(nm: &foreign_mod, fld: @ast_fold) -> foreign_mod { ast::foreign_mod { sort: nm.sort, abis: nm.abis, - view_items: nm.view_items.iter().transform(|x| fld.fold_view_item(*x)).collect(), + view_items: nm.view_items.iter().transform(|x| fld.fold_view_item(x)).collect(), items: nm.items.iter().transform(|x| fld.fold_foreign_item(*x)).collect(), } } fn noop_fold_variant(v: &variant_, fld: @ast_fold) -> variant_ { fn fold_variant_arg_(va: variant_arg, fld: @ast_fold) -> variant_arg { - ast::variant_arg { ty: fld.fold_ty(va.ty), id: fld.new_id(va.id) } + ast::variant_arg { ty: fld.fold_ty(&va.ty), id: fld.new_id(va.id) } } let fold_variant_arg = |x| fold_variant_arg_(x, fld); @@ -723,7 +722,7 @@ fn noop_fold_variant(v: &variant_, fld: @ast_fold) -> variant_ { match v.kind { tuple_variant_kind(ref variant_args) => { kind = tuple_variant_kind(do variant_args.map |x| { - fold_variant_arg(*x) + fold_variant_arg(/*bad*/ copy *x) }) } struct_variant_kind(struct_def) => { @@ -756,20 +755,20 @@ fn noop_fold_ident(i: ident, _fld: @ast_fold) -> ident { /* FIXME (#2543) */ copy i } -fn noop_fold_path(p: @Path, fld: @ast_fold) -> Path { +fn noop_fold_path(p: &Path, fld: @ast_fold) -> Path { ast::Path { span: fld.new_span(p.span), global: p.global, idents: p.idents.map(|x| fld.fold_ident(*x)), rp: p.rp, - types: p.types.map(|x| fld.fold_ty(*x)), + types: p.types.map(|x| fld.fold_ty(x)), } } fn noop_fold_local(l: &local_, fld: @ast_fold) -> local_ { local_ { is_mutbl: l.is_mutbl, - ty: fld.fold_ty(l.ty), + ty: fld.fold_ty(&l.ty), pat: fld.fold_pat(l.pat), init: l.init.map(|e| fld.fold_expr(*e)), id: fld.new_id(l.id), @@ -820,9 +819,8 @@ impl ast_fold for AstFoldFns { let (n, s) = (self.fold_crate)(&c.node, c.span, self as @ast_fold); spanned { node: n, span: (self.new_span)(s) } } - fn fold_view_item(@self, x: @view_item) -> - @view_item { - @ast::view_item { + fn fold_view_item(@self, x: &view_item) -> view_item { + ast::view_item { node: (self.fold_view_item)(&x.node, self as @ast_fold), attrs: x.attrs.iter().transform(|a| fold_attribute_(*a, self as @ast_fold)).collect(), vis: x.vis, @@ -840,7 +838,7 @@ impl ast_fold for AstFoldFns { node: ast::struct_field_ { kind: copy sf.node.kind, id: sf.node.id, - ty: (self as @ast_fold).fold_ty(sf.node.ty), + ty: self.fold_ty(&sf.node.ty), attrs: copy sf.node.attrs, }, span: (self.new_span)(sf.span), @@ -889,9 +887,9 @@ impl ast_fold for AstFoldFns { span: (self.new_span)(s), } } - fn fold_ty(@self, x: @Ty) -> @Ty { + fn fold_ty(@self, x: &Ty) -> Ty { let (n, s) = (self.fold_ty)(&x.node, x.span, self as @ast_fold); - @Ty { + Ty { id: (self.new_id)(x.id), node: n, span: (self.new_span)(s), @@ -910,8 +908,8 @@ impl ast_fold for AstFoldFns { fn fold_ident(@self, x: ident) -> ident { (self.fold_ident)(x, self as @ast_fold) } - fn fold_path(@self, x: @Path) -> @Path { - @(self.fold_path)(x, self as @ast_fold) + fn fold_path(@self, x: &Path) -> Path { + (self.fold_path)(x, self as @ast_fold) } fn fold_local(@self, x: @local) -> @local { let (n, s) = (self.fold_local)(&x.node, x.span, self as @ast_fold); @@ -966,7 +964,7 @@ mod test { } // this version doesn't care about getting comments or docstrings in. - fn fake_print_crate(s: @pprust::ps, crate: ast::crate) { + fn fake_print_crate(s: @pprust::ps, crate: &ast::crate) { pprust::print_mod(s, &crate.node.module, crate.node.attrs); } @@ -997,7 +995,7 @@ mod test { let ast = string_to_crate(@"#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}"); assert_pred!(matches_codepattern, "matches_codepattern", - pprust::to_str(zz_fold.fold_crate(ast),fake_print_crate, + pprust::to_str(&zz_fold.fold_crate(ast),fake_print_crate, token::get_ident_interner()), ~"#[a]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}"); } @@ -1009,7 +1007,7 @@ mod test { => (g $(d $d $e)+))} "); assert_pred!(matches_codepattern, "matches_codepattern", - pprust::to_str(zz_fold.fold_crate(ast),fake_print_crate, + pprust::to_str(&zz_fold.fold_crate(ast),fake_print_crate, token::get_ident_interner()), ~"zz!zz((zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+)))"); } diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index bf8c5ae462bf..ba3b72ec1944 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -16,7 +16,7 @@ * other useful things like `push()` and `len()`. */ -use std::vec::VecIterator; +use std::vec::{VecIterator}; #[deriving(Encodable, Decodable,IterBytes)] pub enum OptVec { @@ -58,6 +58,13 @@ impl OptVec { } } + fn map_consume(self, op: &fn(T) -> U) -> OptVec { + match self { + Empty => Empty, + Vec(v) => Vec(v.consume_iter().transform(op).collect()) + } + } + fn get<'a>(&'a self, i: uint) -> &'a T { match *self { Empty => fail!("Invalid index %u", i), @@ -146,4 +153,12 @@ impl<'self, T> Iterator<&'self T> for OptVecIterator<'self, T> { None => None } } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + match self.iter { + Some(ref x) => x.size_hint(), + None => (0, Some(0)) + } + } } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 6dd8d4880e3f..75d1f35bf38a 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -44,6 +44,8 @@ pub struct ParseSess { cm: @codemap::CodeMap, // better be the same as the one in the reader! next_id: node_id, span_diagnostic: @span_handler, // better be the same as the one in the reader! + /// Used to determine and report recursive mod inclusions + included_mod_stack: ~[Path], } pub fn new_parse_sess(demitter: Option) -> @mut ParseSess { @@ -52,6 +54,7 @@ pub fn new_parse_sess(demitter: Option) -> @mut ParseSess { cm: cm, next_id: 1, span_diagnostic: mk_span_handler(mk_handler(demitter), cm), + included_mod_stack: ~[], } } @@ -62,6 +65,7 @@ pub fn new_parse_sess_special_handler(sh: @span_handler, cm: cm, next_id: 1, span_diagnostic: sh, + included_mod_stack: ~[], } } @@ -366,7 +370,7 @@ mod test { #[test] fn path_exprs_1 () { assert_eq!(string_to_expr(@"a"), @ast::expr{id:1, - node:ast::expr_path(@ast::Path {span:sp(0,1), + node:ast::expr_path(ast::Path {span:sp(0,1), global:false, idents:~[str_to_ident("a")], rp:None, @@ -378,7 +382,7 @@ mod test { assert_eq!(string_to_expr(@"::a::b"), @ast::expr{id:1, node:ast::expr_path( - @ast::Path {span:sp(0,6), + ast::Path {span:sp(0,6), global:true, idents:strs_to_idents(~["a","b"]), rp:None, @@ -428,7 +432,7 @@ mod test { node:ast::expr_ret( Some(@ast::expr{id:1, node:ast::expr_path( - @ast::Path{span:sp(7,8), + ast::Path{span:sp(7,8), global:false, idents:~[str_to_ident("d")], rp:None, @@ -444,7 +448,7 @@ mod test { node: ast::stmt_expr(@ast::expr{ id: 1, node: ast::expr_path( - @ast::Path{ + ast::Path{ span:sp(0,1), global:false, idents:~[str_to_ident("b")], @@ -465,7 +469,7 @@ mod test { assert_eq!(parser.parse_pat(), @ast::pat{id:1, // fixme node: ast::pat_ident(ast::bind_infer, - @ast::Path{ + ast::Path{ span:sp(0,1), global:false, idents:~[str_to_ident("b")], @@ -482,19 +486,19 @@ mod test { assert_eq!(parser.parse_arg_general(true), ast::arg{ is_mutbl: false, - ty: @ast::Ty{id:3, // fixme - node: ast::ty_path(@ast::Path{ + ty: ast::Ty{id:3, // fixme + node: ast::ty_path(ast::Path{ span:sp(4,4), // this is bizarre... // check this in the original parser? global:false, idents:~[str_to_ident("int")], rp: None, types: ~[]}, - @None, 2), + None, 2), span:sp(4,7)}, pat: @ast::pat{id:1, node: ast::pat_ident(ast::bind_infer, - @ast::Path{ + ast::Path{ span:sp(0,1), global:false, idents:~[str_to_ident("b")], @@ -519,19 +523,19 @@ mod test { node: ast::item_fn(ast::fn_decl{ inputs: ~[ast::arg{ is_mutbl: false, - ty: @ast::Ty{id:3, // fixme - node: ast::ty_path(@ast::Path{ + ty: ast::Ty{id:3, // fixme + node: ast::ty_path(ast::Path{ span:sp(10,13), global:false, idents:~[str_to_ident("int")], rp: None, types: ~[]}, - @None, 2), + None, 2), span:sp(10,13)}, pat: @ast::pat{id:1, // fixme node: ast::pat_ident( ast::bind_infer, - @ast::Path{ + ast::Path{ span:sp(6,7), global:false, idents:~[str_to_ident("b")], @@ -542,7 +546,7 @@ mod test { span: sp(6,7)}, id: 4 // fixme }], - output: @ast::Ty{id:5, // fixme + output: ast::Ty{id:5, // fixme node: ast::ty_nil, span:sp(15,15)}, // not sure cf: ast::return_val @@ -561,7 +565,7 @@ mod test { node: ast::stmt_semi(@ast::expr{ id: 6, node: ast::expr_path( - @ast::Path{ + ast::Path{ span:sp(17,18), global:false, idents:~[str_to_ident("b")], diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cc0baa28e20d..c43b350abdbf 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -115,7 +115,7 @@ pub enum item_or_view_item { iovi_none, iovi_item(@item), iovi_foreign_item(@foreign_item), - iovi_view_item(@view_item) + iovi_view_item(view_item) } #[deriving(Eq)] @@ -130,20 +130,28 @@ The important thing is to make sure that lookahead doesn't balk at INTERPOLATED tokens */ macro_rules! maybe_whole_expr ( ($p:expr) => ( - match *($p).token { - INTERPOLATED(token::nt_expr(e)) => { - $p.bump(); - return e; + { + // This horrible convolution is brought to you by + // @mut, have a terrible day + let ret = match *($p).token { + INTERPOLATED(token::nt_expr(e)) => { + Some(e) + } + INTERPOLATED(token::nt_path(ref pt)) => { + Some($p.mk_expr( + ($p).span.lo, + ($p).span.hi, + expr_path(/* bad */ copy *pt))) + } + _ => None + }; + match ret { + Some(e) => { + $p.bump(); + return e; + } + None => () } - INTERPOLATED(token::nt_path(pt)) => { - $p.bump(); - return $p.mk_expr( - ($p).span.lo, - ($p).span.hi, - expr_path(pt) - ); - } - _ => () } ) ) @@ -208,7 +216,7 @@ fn maybe_append(lhs: ~[attribute], rhs: Option<~[attribute]>) struct ParsedItemsAndViewItems { attrs_remaining: ~[attribute], - view_items: ~[@view_item], + view_items: ~[view_item], items: ~[@item], foreign_items: ~[@foreign_item] } @@ -264,7 +272,6 @@ pub struct Parser { obsolete_set: @mut HashSet, /// Used to determine the path to externally loaded source files mod_path_stack: @mut ~[@str], - } #[unsafe_destructor] @@ -638,7 +645,7 @@ impl Parser { // parse a ty_closure type pub fn parse_ty_closure(&self, sigil: ast::Sigil, - region: Option<@ast::Lifetime>) + region: Option) -> ty_ { /* @@ -816,7 +823,7 @@ impl Parser { // parse a possibly mutable type pub fn parse_mt(&self) -> mt { let mutbl = self.parse_mutability(); - let t = self.parse_ty(false); + let t = ~self.parse_ty(false); mt { ty: t, mutbl: mutbl } } @@ -827,7 +834,7 @@ impl Parser { let mutbl = self.parse_mutability(); let id = self.parse_ident(); self.expect(&token::COLON); - let ty = self.parse_ty(false); + let ty = ~self.parse_ty(false); spanned( lo, ty.span.hi, @@ -839,13 +846,13 @@ impl Parser { } // parse optional return type [ -> TY ] in function decl - pub fn parse_ret_ty(&self) -> (ret_style, @Ty) { + pub fn parse_ret_ty(&self) -> (ret_style, Ty) { return if self.eat(&token::RARROW) { let lo = self.span.lo; if self.eat(&token::NOT) { ( noreturn, - @Ty { + Ty { id: self.get_id(), node: ty_bot, span: mk_sp(lo, self.last_span.hi) @@ -858,7 +865,7 @@ impl Parser { let pos = self.span.lo; ( return_val, - @Ty { + Ty { id: self.get_id(), node: ty_nil, span: mk_sp(pos, pos), @@ -870,7 +877,7 @@ impl Parser { // parse a type. // Useless second parameter for compatibility with quasiquote macros. // Bleh! - pub fn parse_ty(&self, _: bool) -> @Ty { + pub fn parse_ty(&self, _: bool) -> Ty { maybe_whole!(self, nt_ty); let lo = self.span.lo; @@ -960,14 +967,14 @@ impl Parser { || is_ident_or_path(self.token) { // NAMED TYPE let (path, bounds) = self.parse_type_path(); - ty_path(path, @bounds, self.get_id()) + ty_path(path, bounds, self.get_id()) } else { self.fatal(fmt!("expected type, found token %?", *self.token)); }; let sp = mk_sp(lo, self.last_span.hi); - @Ty {id: self.get_id(), node: t, span: sp} + Ty {id: self.get_id(), node: t, span: sp} } // parse the type following a @ or a ~ @@ -977,7 +984,7 @@ impl Parser { // @'foo fn() or @foo/fn() or @fn() are parsed directly as fn types: match *self.token { token::LIFETIME(*) => { - let lifetime = @self.parse_lifetime(); + let lifetime = self.parse_lifetime(); self.bump(); return self.parse_ty_closure(sigil, Some(lifetime)); } @@ -986,7 +993,7 @@ impl Parser { if self.look_ahead(1u) == token::BINOP(token::SLASH) && self.token_is_closure_keyword(&self.look_ahead(2u)) { - let lifetime = @self.parse_lifetime(); + let lifetime = self.parse_lifetime(); self.obsolete(*self.last_span, ObsoleteLifetimeNotation); return self.parse_ty_closure(sigil, Some(lifetime)); } else if self.token_is_closure_keyword(© *self.token) { @@ -1108,7 +1115,7 @@ impl Parser { let t = if self.eat(&token::COLON) { self.parse_ty(false) } else { - @Ty { + Ty { id: self.get_id(), node: ty_infer, span: mk_sp(self.span.lo, self.span.hi), @@ -1218,10 +1225,10 @@ impl Parser { } // parse a path that doesn't have type parameters attached - pub fn parse_path_without_tps(&self) -> @ast::Path { + pub fn parse_path_without_tps(&self) -> ast::Path { maybe_whole!(self, nt_path); let (ids,is_global,sp) = self.parse_path(); - @ast::Path { span: sp, + ast::Path { span: sp, global: is_global, idents: ids, rp: None, @@ -1229,7 +1236,7 @@ impl Parser { } pub fn parse_bounded_path_with_tps(&self, colons: bool, - before_tps: Option<&fn()>) -> @ast::Path { + before_tps: Option<&fn()>) -> ast::Path { debug!("parse_path_with_tps(colons=%b)", colons); maybe_whole!(self, nt_path); @@ -1255,7 +1262,7 @@ impl Parser { token::IDENT(sid, _) => { let span = copy self.span; self.bump(); - Some(@ast::Lifetime { + Some(ast::Lifetime { id: self.get_id(), span: *span, ident: sid @@ -1280,7 +1287,7 @@ impl Parser { if v.len() == 0 { None } else if v.len() == 1 { - Some(@*v.get(0)) + Some(*v.get(0)) } else { self.fatal(fmt!("Expected at most one \ lifetime name (for now)")); @@ -1288,22 +1295,22 @@ impl Parser { } }; - @ast::Path { span: mk_sp(lo, hi), + ast::Path { span: mk_sp(lo, hi), rp: rp, types: tps, - .. copy *path } + .. path } } // parse a path optionally with type parameters. If 'colons' // is true, then type parameters must be preceded by colons, // as in a::t:: - pub fn parse_path_with_tps(&self, colons: bool) -> @ast::Path { + pub fn parse_path_with_tps(&self, colons: bool) -> ast::Path { self.parse_bounded_path_with_tps(colons, None) } // Like the above, but can also parse kind bounds in the case of a // path to be used as a type that might be a trait. - pub fn parse_type_path(&self) -> (@ast::Path, Option>) { + pub fn parse_type_path(&self) -> (ast::Path, Option>) { let mut bounds = None; let path = self.parse_bounded_path_with_tps(false, Some(|| { // Note: this closure might not even get called in the case of a @@ -1314,17 +1321,17 @@ impl Parser { } /// parses 0 or 1 lifetime - pub fn parse_opt_lifetime(&self) -> Option<@ast::Lifetime> { + pub fn parse_opt_lifetime(&self) -> Option { match *self.token { token::LIFETIME(*) => { - Some(@self.parse_lifetime()) + Some(self.parse_lifetime()) } // Also accept the (obsolete) syntax `foo/` token::IDENT(*) => { if self.look_ahead(1u) == token::BINOP(token::SLASH) { self.obsolete(*self.last_span, ObsoleteLifetimeNotation); - Some(@self.parse_lifetime()) + Some(self.parse_lifetime()) } else { None } @@ -1455,7 +1462,7 @@ impl Parser { pub fn mk_method_call(&self, rcvr: @expr, ident: ident, - tps: ~[@Ty], + tps: ~[Ty], args: ~[@expr], sugar: CallSugar) -> ast::expr_ { expr_method_call(self.get_id(), rcvr, ident, tps, args, sugar) @@ -1465,7 +1472,7 @@ impl Parser { expr_index(self.get_id(), expr, idx) } - pub fn mk_field(&self, expr: @expr, ident: ident, tys: ~[@Ty]) -> ast::expr_ { + pub fn mk_field(&self, expr: @expr, ident: ident, tys: ~[Ty]) -> ast::expr_ { expr_field(expr, ident, tys) } @@ -1549,10 +1556,10 @@ impl Parser { } else if self.eat_keyword(keywords::If) { return self.parse_if_expr(); } else if self.eat_keyword(keywords::For) { - return self.parse_sugary_call_expr(~"for", ForSugar, + return self.parse_sugary_call_expr(lo, ~"for", ForSugar, expr_loop_body); } else if self.eat_keyword(keywords::Do) { - return self.parse_sugary_call_expr(~"do", DoSugar, + return self.parse_sugary_call_expr(lo, ~"do", DoSugar, expr_do_body); } else if self.eat_keyword(keywords::While) { return self.parse_while_expr(); @@ -2207,7 +2214,7 @@ impl Parser { // No argument list - `do foo {` ast::fn_decl { inputs: ~[], - output: @Ty { + output: Ty { id: self.get_id(), node: ty_infer, span: *self.span @@ -2264,12 +2271,11 @@ impl Parser { // parse a 'for' or 'do'. // the 'for' and 'do' expressions parse as calls, but look like // function calls followed by a closure expression. - pub fn parse_sugary_call_expr(&self, + pub fn parse_sugary_call_expr(&self, lo: BytePos, keyword: ~str, sugar: CallSugar, ctor: &fn(v: @expr) -> expr_) -> @expr { - let lo = self.last_span; // Parse the callee `foo` in // for foo || { // for foo.bar || { @@ -2286,21 +2292,21 @@ impl Parser { let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); let args = vec::append(copy *args, [last_arg]); - self.mk_expr(lo.lo, block.span.hi, expr_call(f, args, sugar)) + self.mk_expr(lo, block.span.hi, expr_call(f, args, sugar)) } expr_method_call(_, f, i, ref tps, ref args, NoSugar) => { let block = self.parse_lambda_block_expr(); let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); let args = vec::append(copy *args, [last_arg]); - self.mk_expr(lo.lo, block.span.hi, + self.mk_expr(lo, block.span.hi, self.mk_method_call(f, i, copy *tps, args, sugar)) } expr_field(f, i, ref tps) => { let block = self.parse_lambda_block_expr(); let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); - self.mk_expr(lo.lo, block.span.hi, + self.mk_expr(lo, block.span.hi, self.mk_method_call(f, i, copy *tps, ~[last_arg], sugar)) } expr_path(*) | expr_call(*) | expr_method_call(*) | @@ -2309,7 +2315,7 @@ impl Parser { let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); self.mk_expr( - lo.lo, + lo, last_arg.span.hi, self.mk_call(e, ~[last_arg], sugar)) } @@ -2319,7 +2325,7 @@ impl Parser { // but they aren't represented by tests debug!("sugary call on %?", e.node); self.span_fatal( - *lo, + e.span, fmt!("`%s` must be followed by a block call", keyword)); } } @@ -2819,7 +2825,7 @@ impl Parser { self.obsolete(*self.span, ObsoleteMutWithMultipleBindings) } - let mut ty = @Ty { + let mut ty = Ty { id: self.get_id(), node: ty_infer, span: mk_sp(lo, lo), @@ -3206,7 +3212,7 @@ impl Parser { let ident = self.parse_ident(); let opt_bounds = self.parse_optional_ty_param_bounds(); // For typarams we don't care about the difference b/w "" and "". - let bounds = @opt_bounds.get_or_default(opt_vec::Empty); + let bounds = opt_bounds.get_or_default(opt_vec::Empty); ast::TyParam { ident: ident, id: self.get_id(), bounds: bounds } } @@ -3228,7 +3234,7 @@ impl Parser { // parse a generic use site fn parse_generic_values( - &self) -> (OptVec, ~[@Ty]) + &self) -> (OptVec, ~[Ty]) { if !self.eat(&token::LT) { (opt_vec::Empty, ~[]) @@ -3238,7 +3244,7 @@ impl Parser { } fn parse_generic_values_after_lt( - &self) -> (OptVec, ~[@Ty]) + &self) -> (OptVec, ~[Ty]) { let lifetimes = self.parse_lifetimes(); let result = self.parse_seq_to_gt( @@ -3336,14 +3342,14 @@ impl Parser { } else if (this.token_is_lifetime(&this.look_ahead(1)) && token::is_keyword(keywords::Self, &this.look_ahead(2))) { this.bump(); - let lifetime = @this.parse_lifetime(); + let lifetime = this.parse_lifetime(); this.expect_self_ident(); sty_region(Some(lifetime), m_imm) } else if (this.token_is_lifetime(&this.look_ahead(1)) && this.token_is_mutability(&this.look_ahead(2)) && token::is_keyword(keywords::Self, &this.look_ahead(3))) { this.bump(); - let lifetime = @this.parse_lifetime(); + let lifetime = this.parse_lifetime(); let mutability = this.parse_mutability(); this.expect_self_ident(); sty_region(Some(lifetime), mutability) @@ -3448,7 +3454,7 @@ impl Parser { let output = if self.eat(&token::RARROW) { self.parse_ty(false) } else { - @Ty { id: self.get_id(), node: ty_infer, span: *self.span } + Ty { id: self.get_id(), node: ty_infer, span: *self.span } }; ast::fn_decl { @@ -3558,9 +3564,9 @@ impl Parser { let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) { // New-style trait. Reinterpret the type as a trait. let opt_trait_ref = match ty.node { - ty_path(path, @None, node_id) => { - Some(@trait_ref { - path: path, + ty_path(ref path, None, node_id) => { + Some(trait_ref { + path: /* bad */ copy *path, ref_id: node_id }) } @@ -3601,15 +3607,15 @@ impl Parser { } // parse a::B<~str,int> - fn parse_trait_ref(&self) -> @trait_ref { - @ast::trait_ref { + fn parse_trait_ref(&self) -> trait_ref { + ast::trait_ref { path: self.parse_path_with_tps(false), ref_id: self.get_id(), } } // parse B + C<~str,int> + D - fn parse_trait_ref_list(&self, ket: &token::Token) -> ~[@trait_ref] { + fn parse_trait_ref_list(&self, ket: &token::Token) -> ~[trait_ref] { self.parse_seq_to_before_end( ket, seq_sep_trailing_disallowed(token::BINOP(token::PLUS)), @@ -3834,7 +3840,7 @@ impl Parser { (id, item_static(ty, m, e), None) } - // parse a mod { ...} item + // parse a `mod { ... }` or `mod ;` item fn parse_item_mod(&self, outer_attrs: ~[ast::attribute]) -> item_info { let id_span = *self.span; let id = self.parse_ident(); @@ -3907,6 +3913,23 @@ impl Parser { prefix.push_many(path.components) }; let full_path = full_path.normalize(); + + let maybe_i = do self.sess.included_mod_stack.iter().position |&p| { p == full_path }; + match maybe_i { + Some(i) => { + let stack = &self.sess.included_mod_stack; + let mut err = ~"circular modules: "; + for stack.slice(i, stack.len()).iter().advance |p| { + err.push_str(p.to_str()); + err.push_str(" -> "); + } + err.push_str(full_path.to_str()); + self.span_fatal(id_sp, err); + } + None => () + } + self.sess.included_mod_stack.push(full_path.clone()); + let p0 = new_sub_parser_from_file(self.sess, copy self.cfg, &full_path, id_sp); @@ -3914,6 +3937,7 @@ impl Parser { let mod_attrs = vec::append(outer_attrs, inner); let first_item_outer_attrs = next; let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs); + self.sess.included_mod_stack.pop(); return (ast::item_mod(m0), mod_attrs); fn cdir_path_opt(default: @str, attrs: ~[ast::attribute]) -> @str { @@ -4075,7 +4099,7 @@ impl Parser { // extern mod foo; let metadata = self.parse_optional_meta(); self.expect(&token::SEMI); - iovi_view_item(@ast::view_item { + iovi_view_item(ast::view_item { node: view_item_extern_mod(ident, metadata, self.get_id()), attrs: copy attrs, vis: visibility, @@ -4148,9 +4172,9 @@ impl Parser { seq_sep_trailing_disallowed(token::COMMA), |p| p.parse_ty(false) ); - for arg_tys.iter().advance |ty| { + for arg_tys.consume_iter().advance |ty| { args.push(ast::variant_arg { - ty: *ty, + ty: ty, id: self.get_id(), }); } @@ -4309,7 +4333,7 @@ impl Parser { // USE ITEM (iovi_view_item) let view_item = self.parse_use(); self.expect(&token::SEMI); - return iovi_view_item(@ast::view_item { + return iovi_view_item(ast::view_item { node: view_item, attrs: attrs, vis: visibility, @@ -4559,7 +4583,7 @@ impl Parser { let id = self.parse_ident(); path.push(id); } - let path = @ast::Path { span: mk_sp(lo, self.span.hi), + let path = ast::Path { span: mk_sp(lo, self.span.hi), global: false, idents: path, rp: None, @@ -4589,7 +4613,7 @@ impl Parser { seq_sep_trailing_allowed(token::COMMA), |p| p.parse_path_list_ident() ); - let path = @ast::Path { span: mk_sp(lo, self.span.hi), + let path = ast::Path { span: mk_sp(lo, self.span.hi), global: false, idents: path, rp: None, @@ -4601,7 +4625,7 @@ impl Parser { // foo::bar::* token::BINOP(token::STAR) => { self.bump(); - let path = @ast::Path { span: mk_sp(lo, self.span.hi), + let path = ast::Path { span: mk_sp(lo, self.span.hi), global: false, idents: path, rp: None, @@ -4617,7 +4641,7 @@ impl Parser { _ => () } let last = path[path.len() - 1u]; - let path = @ast::Path { span: mk_sp(lo, self.span.hi), + let path = ast::Path { span: mk_sp(lo, self.span.hi), global: false, idents: path, rp: None, @@ -4657,7 +4681,7 @@ impl Parser { &self, attrs: ~[attribute], vis: visibility - ) -> @view_item { + ) -> view_item { let lo = self.span.lo; let node = if self.eat_keyword(keywords::Use) { self.parse_use() @@ -4670,7 +4694,7 @@ impl Parser { self.bug("expected view item"); }; self.expect(&token::SEMI); - @ast::view_item { node: node, + ast::view_item { node: node, attrs: attrs, vis: vis, span: mk_sp(lo, self.last_span.hi) } @@ -4688,7 +4712,7 @@ impl Parser { let mut attrs = vec::append(first_item_attrs, self.parse_outer_attributes()); // First, parse view items. - let mut view_items = ~[]; + let mut view_items : ~[ast::view_item] = ~[]; let mut items = ~[]; let mut done = false; // I think this code would probably read better as a single diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index a50fa4168320..09d6ecb40fc0 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -104,9 +104,9 @@ pub enum nonterminal { nt_stmt(@ast::stmt), nt_pat( @ast::pat), nt_expr(@ast::expr), - nt_ty( @ast::Ty), + nt_ty( ast::Ty), nt_ident(ast::ident, bool), - nt_path(@ast::Path), + nt_path( ast::Path), nt_tt( @ast::token_tree), //needs @ed to break a circularity nt_matchers(~[ast::matcher]) } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 5e685d85f95d..b545c56778e9 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -34,9 +34,9 @@ use std::uint; // The @ps is stored here to prevent recursive type. pub enum ann_node<'self> { node_block(@ps, &'self ast::blk), - node_item(@ps, @ast::item), - node_expr(@ps, @ast::expr), - node_pat(@ps, @ast::pat), + node_item(@ps, &'self ast::item), + node_expr(@ps, &'self ast::expr), + node_pat(@ps, &'self ast::pat), } pub struct pp_ann { pre: @fn(ann_node), @@ -106,7 +106,7 @@ pub static default_columns: uint = 78u; pub fn print_crate(cm: @CodeMap, intr: @ident_interner, span_diagnostic: @diagnostic::span_handler, - crate: @ast::crate, + crate: &ast::crate, filename: @str, in: @io::Reader, out: @io::Writer, @@ -136,21 +136,21 @@ pub fn print_crate(cm: @CodeMap, print_crate_(s, crate); } -pub fn print_crate_(s: @ps, crate: @ast::crate) { +pub fn print_crate_(s: @ps, crate: &ast::crate) { print_mod(s, &crate.node.module, crate.node.attrs); print_remaining_comments(s); eof(s.s); } -pub fn ty_to_str(ty: @ast::Ty, intr: @ident_interner) -> ~str { +pub fn ty_to_str(ty: &ast::Ty, intr: @ident_interner) -> ~str { to_str(ty, print_type, intr) } -pub fn pat_to_str(pat: @ast::pat, intr: @ident_interner) -> ~str { +pub fn pat_to_str(pat: &ast::pat, intr: @ident_interner) -> ~str { to_str(pat, print_irrefutable_pat, intr) } -pub fn expr_to_str(e: @ast::expr, intr: @ident_interner) -> ~str { +pub fn expr_to_str(e: &ast::expr, intr: @ident_interner) -> ~str { to_str(e, print_expr, intr) } @@ -158,19 +158,19 @@ pub fn lifetime_to_str(e: &ast::Lifetime, intr: @ident_interner) -> ~str { to_str(e, print_lifetime, intr) } -pub fn tt_to_str(tt: ast::token_tree, intr: @ident_interner) -> ~str { - to_str(&tt, print_tt, intr) +pub fn tt_to_str(tt: &ast::token_tree, intr: @ident_interner) -> ~str { + to_str(tt, print_tt, intr) } pub fn tts_to_str(tts: &[ast::token_tree], intr: @ident_interner) -> ~str { - to_str(tts, print_tts, intr) + to_str(&tts, print_tts, intr) } pub fn stmt_to_str(s: &ast::stmt, intr: @ident_interner) -> ~str { to_str(s, print_stmt, intr) } -pub fn item_to_str(i: @ast::item, intr: @ident_interner) -> ~str { +pub fn item_to_str(i: &ast::item, intr: @ident_interner) -> ~str { to_str(i, print_item, intr) } @@ -179,7 +179,7 @@ pub fn generics_to_str(generics: &ast::Generics, to_str(generics, print_generics, intr) } -pub fn path_to_str(p: @ast::Path, intr: @ident_interner) -> ~str { +pub fn path_to_str(p: &ast::Path, intr: @ident_interner) -> ~str { to_str(p, |a,b| print_path(a, b, false), intr) } @@ -208,11 +208,11 @@ pub fn block_to_str(blk: &ast::blk, intr: @ident_interner) -> ~str { } } -pub fn meta_item_to_str(mi: @ast::meta_item, intr: @ident_interner) -> ~str { +pub fn meta_item_to_str(mi: &ast::meta_item, intr: @ident_interner) -> ~str { to_str(mi, print_meta_item, intr) } -pub fn attribute_to_str(attr: ast::attribute, intr: @ident_interner) -> ~str { +pub fn attribute_to_str(attr: &ast::attribute, intr: @ident_interner) -> ~str { to_str(attr, print_attribute, intr) } @@ -314,30 +314,30 @@ pub fn synth_comment(s: @ps, text: ~str) { word(s.s, "*/"); } -pub fn commasep(s: @ps, b: breaks, elts: &[IN], op: &fn(@ps, IN)) { +pub fn commasep(s: @ps, b: breaks, elts: &[T], op: &fn(@ps, &T)) { box(s, 0u, b); let mut first = true; for elts.iter().advance |elt| { if first { first = false; } else { word_space(s, ","); } - op(s, copy *elt); + op(s, elt); } end(s); } -pub fn commasep_cmnt(s: @ps, b: breaks, elts: &[IN], op: &fn(@ps, IN), - get_span: &fn(IN) -> codemap::span) { +pub fn commasep_cmnt(s: @ps, b: breaks, elts: &[T], op: &fn(@ps, &T), + get_span: &fn(&T) -> codemap::span) { box(s, 0u, b); let len = elts.len(); let mut i = 0u; for elts.iter().advance |elt| { - maybe_print_comment(s, get_span(copy *elt).hi); - op(s, copy *elt); + maybe_print_comment(s, get_span(elt).hi); + op(s, elt); i += 1u; if i < len { word(s.s, ","); - maybe_print_trailing_comment(s, get_span(copy *elt), - Some(get_span(copy elts[i]).hi)); + maybe_print_trailing_comment(s, get_span(elt), + Some(get_span(&elts[i]).hi)); space_if_not_bol(s); } } @@ -345,14 +345,13 @@ pub fn commasep_cmnt(s: @ps, b: breaks, elts: &[IN], op: &fn(@ps, IN), } pub fn commasep_exprs(s: @ps, b: breaks, exprs: &[@ast::expr]) { - fn expr_span(expr: @ast::expr) -> codemap::span { return expr.span; } - commasep_cmnt(s, b, exprs, print_expr, expr_span); + commasep_cmnt(s, b, exprs, |p, &e| print_expr(p, e), |e| e.span); } pub fn print_mod(s: @ps, _mod: &ast::_mod, attrs: &[ast::attribute]) { print_inner_attributes(s, attrs); for _mod.view_items.iter().advance |vitem| { - print_view_item(s, *vitem); + print_view_item(s, vitem); } for _mod.items.iter().advance |item| { print_item(s, *item); } } @@ -361,19 +360,19 @@ pub fn print_foreign_mod(s: @ps, nmod: &ast::foreign_mod, attrs: &[ast::attribute]) { print_inner_attributes(s, attrs); for nmod.view_items.iter().advance |vitem| { - print_view_item(s, *vitem); + print_view_item(s, vitem); } for nmod.items.iter().advance |item| { print_foreign_item(s, *item); } } -pub fn print_opt_lifetime(s: @ps, lifetime: Option<@ast::Lifetime>) { +pub fn print_opt_lifetime(s: @ps, lifetime: &Option) { for lifetime.iter().advance |l| { - print_lifetime(s, *l); + print_lifetime(s, l); nbsp(s); } } -pub fn print_type(s: @ps, ty: @ast::Ty) { +pub fn print_type(s: @ps, ty: &ast::Ty) { maybe_print_comment(s, ty.span.lo); ibox(s, 0u); match ty.node { @@ -392,7 +391,7 @@ pub fn print_type(s: @ps, ty: @ast::Ty) { word(s.s, "]"); } ast::ty_ptr(ref mt) => { word(s.s, "*"); print_mt(s, mt); } - ast::ty_rptr(lifetime, ref mt) => { + ast::ty_rptr(ref lifetime, ref mt) => { word(s.s, "&"); print_opt_lifetime(s, lifetime); print_mt(s, mt); @@ -408,18 +407,18 @@ pub fn print_type(s: @ps, ty: @ast::Ty) { ast::ty_bare_fn(f) => { let generics = ast::Generics {lifetimes: copy f.lifetimes, ty_params: opt_vec::Empty}; - print_ty_fn(s, Some(f.abis), None, None, + print_ty_fn(s, Some(f.abis), None, &None, f.purity, ast::Many, &f.decl, None, &None, Some(&generics), None); } ast::ty_closure(f) => { let generics = ast::Generics {lifetimes: copy f.lifetimes, ty_params: opt_vec::Empty}; - print_ty_fn(s, None, Some(f.sigil), f.region, + print_ty_fn(s, None, Some(f.sigil), &f.region, f.purity, f.onceness, &f.decl, None, &f.bounds, Some(&generics), None); } - ast::ty_path(path, bounds, _) => print_bounded_path(s, path, bounds), + ast::ty_path(ref path, ref bounds, _) => print_bounded_path(s, path, bounds), ast::ty_fixed_length_vec(ref mt, v) => { word(s.s, "["); match mt.mutbl { @@ -443,7 +442,7 @@ pub fn print_type(s: @ps, ty: @ast::Ty) { end(s); } -pub fn print_foreign_item(s: @ps, item: @ast::foreign_item) { +pub fn print_foreign_item(s: @ps, item: &ast::foreign_item) { hardbreak_if_not_bol(s); maybe_print_comment(s, item.span.lo); print_outer_attributes(s, item.attrs); @@ -455,7 +454,7 @@ pub fn print_foreign_item(s: @ps, item: @ast::foreign_item) { word(s.s, ";"); end(s); // end the outer fn box } - ast::foreign_item_static(t, m) => { + ast::foreign_item_static(ref t, m) => { head(s, "static"); if m { word_space(s, "mut"); @@ -470,14 +469,14 @@ pub fn print_foreign_item(s: @ps, item: @ast::foreign_item) { } } -pub fn print_item(s: @ps, item: @ast::item) { +pub fn print_item(s: @ps, item: &ast::item) { hardbreak_if_not_bol(s); maybe_print_comment(s, item.span.lo); print_outer_attributes(s, item.attrs); let ann_node = node_item(s, item); (s.ann.pre)(ann_node); match item.node { - ast::item_static(ty, m, expr) => { + ast::item_static(ref ty, m, expr) => { head(s, visibility_qualified(item.vis, "static")); if m == ast::m_mutbl { word_space(s, "mut"); @@ -531,7 +530,7 @@ pub fn print_item(s: @ps, item: @ast::item) { print_foreign_mod(s, nmod, item.attrs); bclose(s, item.span); } - ast::item_ty(ty, ref params) => { + ast::item_ty(ref ty, ref params) => { ibox(s, indent_unit); ibox(s, 0u); word_nbsp(s, visibility_qualified(item.vis, "type")); @@ -560,7 +559,7 @@ pub fn print_item(s: @ps, item: @ast::item) { print_struct(s, struct_def, generics, item.ident, item.span); } - ast::item_impl(ref generics, opt_trait, ty, ref methods) => { + ast::item_impl(ref generics, ref opt_trait, ref ty, ref methods) => { head(s, visibility_qualified(item.vis, "impl")); if generics.is_parameterized() { print_generics(s, generics); @@ -568,12 +567,12 @@ pub fn print_item(s: @ps, item: @ast::item) { } match opt_trait { - Some(t) => { + &Some(ref t) => { print_trait_ref(s, t); space(s.s); word_space(s, "for"); } - None => () + &None => () }; print_type(s, ty); @@ -600,7 +599,7 @@ pub fn print_item(s: @ps, item: @ast::item) { if i != 0 { word_space(s, "+"); } - print_path(s, trait_.path, false); + print_path(s, &trait_.path, false); } } word(s.s, " "); @@ -610,7 +609,7 @@ pub fn print_item(s: @ps, item: @ast::item) { } bclose(s, item.span); } - ast::item_mac(codemap::spanned { node: ast::mac_invoc_tt(pth, ref tts), + ast::item_mac(codemap::spanned { node: ast::mac_invoc_tt(ref pth, ref tts), _}) => { print_visibility(s, item.vis); print_path(s, pth, false); @@ -618,7 +617,7 @@ pub fn print_item(s: @ps, item: @ast::item) { print_ident(s, item.ident); cbox(s, indent_unit); popen(s); - print_tts(s, *tts); + print_tts(s, &(tts.as_slice())); pclose(s); end(s); } @@ -627,7 +626,7 @@ pub fn print_item(s: @ps, item: @ast::item) { } fn print_trait_ref(s: @ps, t: &ast::trait_ref) { - print_path(s, t.path, false); + print_path(s, &t.path, false); } pub fn print_enum_def(s: @ps, enum_definition: &ast::enum_def, @@ -681,7 +680,7 @@ pub fn print_visibility(s: @ps, vis: ast::visibility) { } pub fn print_struct(s: @ps, - struct_def: @ast::struct_def, + struct_def: &ast::struct_def, generics: &ast::Generics, ident: ast::ident, span: codemap::span) { @@ -695,7 +694,7 @@ pub fn print_struct(s: @ps, ast::named_field(*) => fail!("unexpected named field"), ast::unnamed_field => { maybe_print_comment(s, field.span.lo); - print_type(s, field.node.ty); + print_type(s, &field.node.ty); } } } @@ -719,7 +718,7 @@ pub fn print_struct(s: @ps, print_visibility(s, visibility); print_ident(s, ident); word_nbsp(s, ":"); - print_type(s, field.node.ty); + print_type(s, &field.node.ty); word(s.s, ","); } } @@ -738,7 +737,7 @@ pub fn print_struct(s: @ps, /// expression arguments as expressions). It can be done! I think. pub fn print_tt(s: @ps, tt: &ast::token_tree) { match *tt { - ast::tt_delim(ref tts) => print_tts(s, *tts), + ast::tt_delim(ref tts) => print_tts(s, &(tts.as_slice())), ast::tt_tok(_, ref tk) => { word(s.s, parse::token::to_str(s.intr, tk)); } @@ -759,7 +758,7 @@ pub fn print_tt(s: @ps, tt: &ast::token_tree) { } } -pub fn print_tts(s: @ps, tts: &[ast::token_tree]) { +pub fn print_tts(s: @ps, tts: & &[ast::token_tree]) { ibox(s, 0); for tts.iter().enumerate().advance |(i, tt)| { if i != 0 { @@ -777,8 +776,8 @@ pub fn print_variant(s: @ps, v: &ast::variant) { print_ident(s, v.node.name); if !args.is_empty() { popen(s); - fn print_variant_arg(s: @ps, arg: ast::variant_arg) { - print_type(s, arg.ty); + fn print_variant_arg(s: @ps, arg: &ast::variant_arg) { + print_type(s, &arg.ty); } commasep(s, consistent, *args, print_variant_arg); pclose(s); @@ -804,7 +803,7 @@ pub fn print_ty_method(s: @ps, m: &ast::ty_method) { hardbreak_if_not_bol(s); maybe_print_comment(s, m.span.lo); print_outer_attributes(s, m.attrs); - print_ty_fn(s, None, None, None, m.purity, ast::Many, + print_ty_fn(s, None, None, &None, m.purity, ast::Many, &m.decl, Some(m.ident), &None, Some(&m.generics), Some(/*bad*/ copy m.explicit_self.node)); word(s.s, ";"); @@ -817,7 +816,7 @@ pub fn print_trait_method(s: @ps, m: &ast::trait_method) { } } -pub fn print_method(s: @ps, meth: @ast::method) { +pub fn print_method(s: @ps, meth: &ast::method) { hardbreak_if_not_bol(s); maybe_print_comment(s, meth.span.lo); print_outer_attributes(s, meth.attrs); @@ -832,7 +831,7 @@ pub fn print_outer_attributes(s: @ps, attrs: &[ast::attribute]) { let mut count = 0; for attrs.iter().advance |attr| { match attr.node.style { - ast::attr_outer => { print_attribute(s, *attr); count += 1; } + ast::attr_outer => { print_attribute(s, attr); count += 1; } _ => {/* fallthrough */ } } } @@ -844,7 +843,7 @@ pub fn print_inner_attributes(s: @ps, attrs: &[ast::attribute]) { for attrs.iter().advance |attr| { match attr.node.style { ast::attr_inner => { - print_attribute(s, *attr); + print_attribute(s, attr); if !attr.node.is_sugared_doc { word(s.s, ";"); } @@ -856,11 +855,11 @@ pub fn print_inner_attributes(s: @ps, attrs: &[ast::attribute]) { if count > 0 { hardbreak_if_not_bol(s); } } -pub fn print_attribute(s: @ps, attr: ast::attribute) { +pub fn print_attribute(s: @ps, attr: &ast::attribute) { hardbreak_if_not_bol(s); maybe_print_comment(s, attr.span.lo); if attr.node.is_sugared_doc { - let meta = attr::attr_meta(attr); + let meta = attr::attr_meta(*attr); let comment = attr::get_meta_item_value_str(meta).get(); word(s.s, comment); } else { @@ -947,7 +946,7 @@ pub fn print_possibly_embedded_block_(s: @ps, print_inner_attributes(s, attrs); - for blk.node.view_items.iter().advance |vi| { print_view_item(s, *vi); } + for blk.node.view_items.iter().advance |vi| { print_view_item(s, vi); } for blk.node.stmts.iter().advance |st| { print_stmt(s, *st); } @@ -963,7 +962,7 @@ pub fn print_possibly_embedded_block_(s: @ps, (s.ann.post)(ann_node); } -pub fn print_if(s: @ps, test: @ast::expr, blk: &ast::blk, +pub fn print_if(s: @ps, test: &ast::expr, blk: &ast::blk, elseopt: Option<@ast::expr>, chk: bool) { head(s, "if"); if chk { word_nbsp(s, "check"); } @@ -1005,11 +1004,11 @@ pub fn print_if(s: @ps, test: @ast::expr, blk: &ast::blk, pub fn print_mac(s: @ps, m: &ast::mac) { match m.node { - ast::mac_invoc_tt(pth, ref tts) => { + ast::mac_invoc_tt(ref pth, ref tts) => { print_path(s, pth, false); word(s.s, "!"); popen(s); - print_tts(s, *tts); + print_tts(s, &tts.as_slice()); pclose(s); } } @@ -1021,7 +1020,7 @@ pub fn print_vstore(s: @ps, t: ast::vstore) { ast::vstore_fixed(None) => word(s.s, "_"), ast::vstore_uniq => word(s.s, "~"), ast::vstore_box => word(s.s, "@"), - ast::vstore_slice(r) => { + ast::vstore_slice(ref r) => { word(s.s, "&"); print_opt_lifetime(s, r); } @@ -1088,15 +1087,15 @@ pub fn print_call_post(s: @ps, } } -pub fn print_expr(s: @ps, expr: @ast::expr) { - fn print_field(s: @ps, field: ast::field) { +pub fn print_expr(s: @ps, expr: &ast::expr) { + fn print_field(s: @ps, field: &ast::field) { ibox(s, indent_unit); print_ident(s, field.node.ident); word_space(s, ":"); print_expr(s, field.node.expr); end(s); } - fn get_span(field: ast::field) -> codemap::span { return field.span; } + fn get_span(field: &ast::field) -> codemap::span { return field.span; } maybe_print_comment(s, expr.span.lo); ibox(s, indent_unit); @@ -1134,7 +1133,7 @@ pub fn print_expr(s: @ps, expr: @ast::expr) { end(s); } - ast::expr_struct(path, ref fields, wth) => { + ast::expr_struct(ref path, ref fields, wth) => { print_path(s, path, true); word(s.s, "{"); commasep_cmnt(s, consistent, (*fields), print_field, get_span); @@ -1199,7 +1198,7 @@ pub fn print_expr(s: @ps, expr: @ast::expr) { print_expr(s, expr); } ast::expr_lit(lit) => print_literal(s, lit), - ast::expr_cast(expr, ty) => { + ast::expr_cast(expr, ref ty) => { print_expr(s, expr); space(s.s); word_space(s, "as"); @@ -1359,7 +1358,7 @@ pub fn print_expr(s: @ps, expr: @ast::expr) { print_expr(s, index); word(s.s, "]"); } - ast::expr_path(path) => print_path(s, path, true), + ast::expr_path(ref path) => print_path(s, path, true), ast::expr_self => word(s.s, "self"), ast::expr_break(opt_ident) => { word(s.s, "break"); @@ -1434,15 +1433,15 @@ pub fn print_expr(s: @ps, expr: @ast::expr) { end(s); } -pub fn print_local_decl(s: @ps, loc: @ast::local) { +pub fn print_local_decl(s: @ps, loc: &ast::local) { print_irrefutable_pat(s, loc.node.pat); match loc.node.ty.node { ast::ty_infer => (), - _ => { word_space(s, ":"); print_type(s, loc.node.ty); } + _ => { word_space(s, ":"); print_type(s, &loc.node.ty); } } } -pub fn print_decl(s: @ps, decl: @ast::decl) { +pub fn print_decl(s: @ps, decl: &ast::decl) { maybe_print_comment(s, decl.span.lo); match decl.node { ast::decl_local(ref loc) => { @@ -1454,7 +1453,7 @@ pub fn print_decl(s: @ps, decl: @ast::decl) { word_nbsp(s, "mut"); } - fn print_local(s: @ps, loc: @ast::local) { + fn print_local(s: @ps, loc: &ast::local) { ibox(s, indent_unit); print_local_decl(s, loc); end(s); @@ -1479,14 +1478,14 @@ pub fn print_ident(s: @ps, ident: ast::ident) { word(s.s, ident_to_str(&ident)); } -pub fn print_for_decl(s: @ps, loc: @ast::local, coll: @ast::expr) { +pub fn print_for_decl(s: @ps, loc: &ast::local, coll: &ast::expr) { print_local_decl(s, loc); space(s.s); word_space(s, "in"); print_expr(s, coll); } -fn print_path_(s: @ps, path: @ast::Path, colons_before_params: bool, +fn print_path_(s: @ps, path: &ast::Path, colons_before_params: bool, opt_bounds: &Option>) { maybe_print_comment(s, path.span.lo); if path.global { word(s.s, "::"); } @@ -1505,7 +1504,7 @@ fn print_path_(s: @ps, path: @ast::Path, colons_before_params: bool, word(s.s, "<"); for path.rp.iter().advance |r| { - print_lifetime(s, *r); + print_lifetime(s, r); if !path.types.is_empty() { word_space(s, ","); } @@ -1518,24 +1517,24 @@ fn print_path_(s: @ps, path: @ast::Path, colons_before_params: bool, } } -pub fn print_path(s: @ps, path: @ast::Path, colons_before_params: bool) { +pub fn print_path(s: @ps, path: &ast::Path, colons_before_params: bool) { print_path_(s, path, colons_before_params, &None) } -pub fn print_bounded_path(s: @ps, path: @ast::Path, +pub fn print_bounded_path(s: @ps, path: &ast::Path, bounds: &Option>) { print_path_(s, path, false, bounds) } -pub fn print_irrefutable_pat(s: @ps, pat: @ast::pat) { +pub fn print_irrefutable_pat(s: @ps, pat: &ast::pat) { print_pat(s, pat, false) } -pub fn print_refutable_pat(s: @ps, pat: @ast::pat) { +pub fn print_refutable_pat(s: @ps, pat: &ast::pat) { print_pat(s, pat, true) } -pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { +pub fn print_pat(s: @ps, pat: &ast::pat, refutable: bool) { maybe_print_comment(s, pat.span.lo); let ann_node = node_pat(s, pat); (s.ann.pre)(ann_node); @@ -1543,7 +1542,7 @@ pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { is that it doesn't matter */ match pat.node { ast::pat_wild => word(s.s, "_"), - ast::pat_ident(binding_mode, path, sub) => { + ast::pat_ident(binding_mode, ref path, sub) => { if refutable { match binding_mode { ast::bind_by_ref(mutbl) => { @@ -1562,7 +1561,7 @@ pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { None => () } } - ast::pat_enum(path, ref args_) => { + ast::pat_enum(ref path, ref args_) => { print_path(s, path, true); match *args_ { None => word(s.s, "(*)"), @@ -1570,23 +1569,23 @@ pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { if !args.is_empty() { popen(s); commasep(s, inconsistent, *args, - |s, p| print_pat(s, p, refutable)); + |s, &p| print_pat(s, p, refutable)); pclose(s); } else { } } } } - ast::pat_struct(path, ref fields, etc) => { + ast::pat_struct(ref path, ref fields, etc) => { print_path(s, path, true); word(s.s, "{"); - fn print_field(s: @ps, f: ast::field_pat, refutable: bool) { + fn print_field(s: @ps, f: &ast::field_pat, refutable: bool) { cbox(s, indent_unit); print_ident(s, f.ident); word_space(s, ":"); print_pat(s, f.pat, refutable); end(s); } - fn get_span(f: ast::field_pat) -> codemap::span { return f.pat.span; } + fn get_span(f: &ast::field_pat) -> codemap::span { return f.pat.span; } commasep_cmnt(s, consistent, *fields, |s, f| print_field(s,f,refutable), get_span); @@ -1598,7 +1597,7 @@ pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { } ast::pat_tup(ref elts) => { popen(s); - commasep(s, inconsistent, *elts, |s, p| print_pat(s, p, refutable)); + commasep(s, inconsistent, *elts, |s, &p| print_pat(s, p, refutable)); if elts.len() == 1 { word(s.s, ","); } @@ -1625,7 +1624,7 @@ pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { } ast::pat_vec(ref before, slice, ref after) => { word(s.s, "["); - do commasep(s, inconsistent, *before) |s, p| { + do commasep(s, inconsistent, *before) |s, &p| { print_pat(s, p, refutable); } for slice.iter().advance |&p| { @@ -1634,7 +1633,7 @@ pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { print_pat(s, p, refutable); if !after.is_empty() { word_space(s, ","); } } - do commasep(s, inconsistent, *after) |s, p| { + do commasep(s, inconsistent, *after) |s, &p| { print_pat(s, p, refutable); } word(s.s, "]"); @@ -1643,8 +1642,8 @@ pub fn print_pat(s: @ps, pat: @ast::pat, refutable: bool) { (s.ann.post)(ann_node); } -pub fn explicit_self_to_str(explicit_self: ast::explicit_self_, intr: @ident_interner) -> ~str { - to_str(explicit_self, |a, b| { print_explicit_self(a, b); () }, intr) +pub fn explicit_self_to_str(explicit_self: &ast::explicit_self_, intr: @ident_interner) -> ~str { + to_str(explicit_self, |a, &b| { print_explicit_self(a, b); () }, intr) } // Returns whether it printed anything @@ -1653,7 +1652,7 @@ pub fn print_explicit_self(s: @ps, explicit_self: ast::explicit_self_) -> bool { ast::sty_static => { return false; } ast::sty_value => { word(s.s, "self"); } ast::sty_uniq => { word(s.s, "~self"); } - ast::sty_region(lt, m) => { + ast::sty_region(ref lt, m) => { word(s.s, "&"); print_opt_lifetime(s, lt); print_mutability(s, m); @@ -1694,7 +1693,7 @@ pub fn print_fn_args(s: @ps, decl: &ast::fn_decl, for decl.inputs.iter().advance |arg| { if first { first = false; } else { word_space(s, ","); } - print_arg(s, *arg); + print_arg(s, arg); } end(s); @@ -1712,7 +1711,7 @@ pub fn print_fn_args_and_ret(s: @ps, decl: &ast::fn_decl, _ => { space_if_not_bol(s); word_space(s, "->"); - print_type(s, decl.output); + print_type(s, &decl.output); } } } @@ -1727,7 +1726,7 @@ pub fn print_fn_block_args(s: @ps, decl: &ast::fn_decl) { _ => { space_if_not_bol(s); word_space(s, "->"); - print_type(s, decl.output); + print_type(s, &decl.output); } } @@ -1748,7 +1747,7 @@ pub fn print_bounds(s: @ps, bounds: &OptVec, } match *bound { - TraitTyParamBound(tref) => print_trait_ref(s, tref), + TraitTyParamBound(ref tref) => print_trait_ref(s, tref), RegionTyParamBound => word(s.s, "'static"), } } @@ -1774,7 +1773,7 @@ pub fn print_generics(s: @ps, generics: &ast::Generics) { let idx = idx - generics.lifetimes.len(); let param = generics.ty_params.get(idx); print_ident(s, param.ident); - print_bounds(s, param.bounds, false); + print_bounds(s, ¶m.bounds, false); } } @@ -1784,12 +1783,12 @@ pub fn print_generics(s: @ps, generics: &ast::Generics) { } commasep(s, inconsistent, ints, - |s, i| print_item(s, generics, i)); + |s, &i| print_item(s, generics, i)); word(s.s, ">"); } } -pub fn print_meta_item(s: @ps, item: @ast::meta_item) { +pub fn print_meta_item(s: @ps, item: &ast::meta_item) { ibox(s, indent_unit); match item.node { ast::meta_word(name) => word(s.s, name), @@ -1804,8 +1803,8 @@ pub fn print_meta_item(s: @ps, item: @ast::meta_item) { commasep( s, consistent, - /* FIXME (#2543) */ copy *items, - print_meta_item + items.as_slice(), + |p, &i| print_meta_item(p, i) ); pclose(s); } @@ -1813,9 +1812,9 @@ pub fn print_meta_item(s: @ps, item: @ast::meta_item) { end(s); } -pub fn print_view_path(s: @ps, vp: @ast::view_path) { +pub fn print_view_path(s: @ps, vp: &ast::view_path) { match vp.node { - ast::view_path_simple(ident, path, _) => { + ast::view_path_simple(ident, ref path, _) => { if path.idents[path.idents.len()-1u] != ident { print_ident(s, ident); space(s.s); @@ -1824,12 +1823,12 @@ pub fn print_view_path(s: @ps, vp: @ast::view_path) { print_path(s, path, false); } - ast::view_path_glob(path, _) => { + ast::view_path_glob(ref path, _) => { print_path(s, path, false); word(s.s, "::*"); } - ast::view_path_list(path, ref idents, _) => { + ast::view_path_list(ref path, ref idents, _) => { print_path(s, path, false); word(s.s, "::{"); do commasep(s, inconsistent, (*idents)) |s, w| { @@ -1841,10 +1840,10 @@ pub fn print_view_path(s: @ps, vp: @ast::view_path) { } pub fn print_view_paths(s: @ps, vps: &[@ast::view_path]) { - commasep(s, inconsistent, vps, print_view_path); + commasep(s, inconsistent, vps, |p, &vp| print_view_path(p, vp)); } -pub fn print_view_item(s: @ps, item: @ast::view_item) { +pub fn print_view_item(s: @ps, item: &ast::view_item) { hardbreak_if_not_bol(s); maybe_print_comment(s, item.span.lo); print_outer_attributes(s, item.attrs); @@ -1855,7 +1854,7 @@ pub fn print_view_item(s: @ps, item: @ast::view_item) { print_ident(s, id); if !mta.is_empty() { popen(s); - commasep(s, consistent, *mta, print_meta_item); + commasep(s, consistent, *mta, |p, &i| print_meta_item(p, i)); pclose(s); } } @@ -1883,7 +1882,7 @@ pub fn print_mt(s: @ps, mt: &ast::mt) { print_type(s, mt.ty); } -pub fn print_arg(s: @ps, input: ast::arg) { +pub fn print_arg(s: @ps, input: &ast::arg) { ibox(s, indent_unit); if input.is_mutbl { word_space(s, "mut"); @@ -1892,7 +1891,7 @@ pub fn print_arg(s: @ps, input: ast::arg) { ast::ty_infer => print_irrefutable_pat(s, input.pat), _ => { match input.pat.node { - ast::pat_ident(_, path, _) if + ast::pat_ident(_, ref path, _) if path.idents.len() == 1 && path.idents[0] == parse::token::special_idents::invalid => { // Do nothing. @@ -1903,7 +1902,7 @@ pub fn print_arg(s: @ps, input: ast::arg) { space(s.s); } } - print_type(s, input.ty); + print_type(s, &input.ty); } } end(s); @@ -1912,7 +1911,7 @@ pub fn print_arg(s: @ps, input: ast::arg) { pub fn print_ty_fn(s: @ps, opt_abis: Option, opt_sigil: Option, - opt_region: Option<@ast::Lifetime>, + opt_region: &Option, purity: ast::purity, onceness: ast::Onceness, decl: &ast::fn_decl, @@ -1945,7 +1944,7 @@ pub fn print_ty_fn(s: @ps, } for decl.inputs.iter().advance |arg| { if first { first = false; } else { word_space(s, ","); } - print_arg(s, *arg); + print_arg(s, arg); } end(s); pclose(s); @@ -1959,7 +1958,7 @@ pub fn print_ty_fn(s: @ps, ibox(s, indent_unit); word_space(s, "->"); if decl.cf == ast::noreturn { word_nbsp(s, "!"); } - else { print_type(s, decl.output); } + else { print_type(s, &decl.output); } end(s); } } @@ -2003,7 +2002,7 @@ pub fn print_remaining_comments(s: @ps) { } } -pub fn print_literal(s: @ps, lit: @ast::lit) { +pub fn print_literal(s: @ps, lit: &ast::lit) { maybe_print_comment(s, lit.span.lo); match next_lit(s, lit.span.lo) { Some(ref ltrl) => { @@ -2056,7 +2055,7 @@ pub fn print_literal(s: @ps, lit: @ast::lit) { } } -pub fn lit_to_str(l: @ast::lit) -> ~str { +pub fn lit_to_str(l: &ast::lit) -> ~str { return to_str(l, print_literal, parse::token::mk_fake_ident_interner()); } @@ -2139,10 +2138,10 @@ pub fn print_string(s: @ps, st: &str) { word(s.s, "\""); } -pub fn to_str(t: T, f: @fn(@ps, T), intr: @ident_interner) -> ~str { +pub fn to_str(t: &T, f: &fn(@ps, &T), intr: @ident_interner) -> ~str { do io::with_str_writer |wr| { let s = rust_printer(wr, intr); - f(s, copy t); + f(s, t); eof(s.s); } } @@ -2273,7 +2272,7 @@ mod test { let decl = ast::fn_decl { inputs: ~[], - output: @ast::Ty {id: 0, + output: ast::Ty {id: 0, node: ast::ty_nil, span: codemap::dummy_sp()}, cf: ast::return_val diff --git a/src/libsyntax/syntax.rs b/src/libsyntax/syntax.rs index 830ca5694553..7cb211a402b4 100644 --- a/src/libsyntax/syntax.rs +++ b/src/libsyntax/syntax.rs @@ -14,13 +14,14 @@ */ #[link(name = "syntax", - vers = "0.7", + vers = "0.8-pre", uuid = "9311401b-d6ea-4cd9-a1d9-61f89499c645")]; #[license = "MIT/ASL2"]; #[crate_type = "lib"]; #[allow(non_camel_case_types)]; +#[allow(non_uppercase_statics)]; #[deny(deprecated_pattern)]; extern mod extra; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 9fcffc110130..b2d9d49f0ee7 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -72,7 +72,7 @@ pub fn generics_of_fn(fk: &fn_kind) -> Generics { pub struct Visitor { visit_mod: @fn(&_mod, span, node_id, (E, vt)), - visit_view_item: @fn(@view_item, (E, vt)), + visit_view_item: @fn(&view_item, (E, vt)), visit_foreign_item: @fn(@foreign_item, (E, vt)), visit_item: @fn(@item, (E, vt)), visit_local: @fn(@local, (E, vt)), @@ -83,14 +83,13 @@ pub struct Visitor { visit_decl: @fn(@decl, (E, vt)), visit_expr: @fn(@expr, (E, vt)), visit_expr_post: @fn(@expr, (E, vt)), - visit_ty: @fn(@Ty, (E, vt)), + visit_ty: @fn(&Ty, (E, vt)), visit_generics: @fn(&Generics, (E, vt)), visit_fn: @fn(&fn_kind, &fn_decl, &blk, span, node_id, (E, vt)), visit_ty_method: @fn(&ty_method, (E, vt)), visit_trait_method: @fn(&trait_method, (E, vt)), visit_struct_def: @fn(@struct_def, ident, &Generics, node_id, (E, vt)), visit_struct_field: @fn(@struct_field, (E, vt)), - visit_struct_method: @fn(@method, (E, vt)) } pub type visitor = @Visitor; @@ -116,7 +115,6 @@ pub fn default_visitor() -> visitor { visit_trait_method: |a,b|visit_trait_method::(a, b), visit_struct_def: |a,b,c,d,e|visit_struct_def::(a, b, c, d, e), visit_struct_field: |a,b|visit_struct_field::(a, b), - visit_struct_method: |a,b|visit_struct_method::(a, b) }; } @@ -125,7 +123,7 @@ pub fn visit_crate(c: &crate, (e, v): (E, vt)) { } pub fn visit_mod(m: &_mod, _sp: span, _id: node_id, (e, v): (E, vt)) { - for m.view_items.iter().advance |vi| { (v.visit_view_item)(*vi, (copy e, v)); } + for m.view_items.iter().advance |vi| { (v.visit_view_item)(vi, (copy e, v)); } for m.items.iter().advance |i| { (v.visit_item)(*i, (copy e, v)); } } @@ -133,7 +131,7 @@ pub fn visit_view_item(_vi: &view_item, (_e, _v): (E, vt)) { } pub fn visit_local(loc: &local, (e, v): (E, vt)) { (v.visit_pat)(loc.node.pat, (copy e, v)); - (v.visit_ty)(loc.node.ty, (copy e, v)); + (v.visit_ty)(&loc.node.ty, (copy e, v)); match loc.node.init { None => (), Some(ex) => (v.visit_expr)(ex, (e, v)) @@ -141,12 +139,12 @@ pub fn visit_local(loc: &local, (e, v): (E, vt)) { } fn visit_trait_ref(tref: &ast::trait_ref, (e, v): (E, vt)) { - visit_path(tref.path, (e, v)); + visit_path(&tref.path, (e, v)); } pub fn visit_item(i: &item, (e, v): (E, vt)) { match i.node { - item_static(t, _, ex) => { + item_static(ref t, _, ex) => { (v.visit_ty)(t, (copy e, v)); (v.visit_expr)(ex, (copy e, v)); } @@ -168,10 +166,10 @@ pub fn visit_item(i: &item, (e, v): (E, vt)) { } item_mod(ref m) => (v.visit_mod)(m, i.span, i.id, (e, v)), item_foreign_mod(ref nm) => { - for nm.view_items.iter().advance |vi| { (v.visit_view_item)(*vi, (copy e, v)); } + for nm.view_items.iter().advance |vi| { (v.visit_view_item)(vi, (copy e, v)); } for nm.items.iter().advance |ni| { (v.visit_foreign_item)(*ni, (copy e, v)); } } - item_ty(t, ref tps) => { + item_ty(ref t, ref tps) => { (v.visit_ty)(t, (copy e, v)); (v.visit_generics)(tps, (e, v)); } @@ -183,9 +181,9 @@ pub fn visit_item(i: &item, (e, v): (E, vt)) { (e, v) ); } - item_impl(ref tps, ref traits, ty, ref methods) => { + item_impl(ref tps, ref traits, ref ty, ref methods) => { (v.visit_generics)(tps, (copy e, v)); - for traits.iter().advance |&p| { + for traits.iter().advance |p| { visit_trait_ref(p, (copy e, v)); } (v.visit_ty)(ty, (copy e, v)); @@ -199,7 +197,7 @@ pub fn visit_item(i: &item, (e, v): (E, vt)) { } item_trait(ref generics, ref traits, ref methods) => { (v.visit_generics)(generics, (copy e, v)); - for traits.iter().advance |p| { visit_path(p.path, (copy e, v)); } + for traits.iter().advance |p| { visit_path(&p.path, (copy e, v)); } for methods.iter().advance |m| { (v.visit_trait_method)(m, (copy e, v)); } @@ -215,7 +213,7 @@ pub fn visit_enum_def(enum_definition: &ast::enum_def, match vr.node.kind { tuple_variant_kind(ref variant_args) => { for variant_args.iter().advance |va| { - (v.visit_ty)(va.ty, (copy e, v)); + (v.visit_ty)(&va.ty, (copy e, v)); } } struct_variant_kind(struct_def) => { @@ -234,27 +232,27 @@ pub fn skip_ty(_t: &Ty, (_e,_v): (E, vt)) {} pub fn visit_ty(t: &Ty, (e, v): (E, vt)) { match t.node { - ty_box(mt) | ty_uniq(mt) | - ty_vec(mt) | ty_ptr(mt) | ty_rptr(_, mt) => { + ty_box(ref mt) | ty_uniq(ref mt) | + ty_vec(ref mt) | ty_ptr(ref mt) | ty_rptr(_, ref mt) => { (v.visit_ty)(mt.ty, (e, v)); }, ty_tup(ref ts) => { for ts.iter().advance |tt| { - (v.visit_ty)(*tt, (copy e, v)); + (v.visit_ty)(tt, (copy e, v)); } }, ty_closure(ref f) => { - for f.decl.inputs.iter().advance |a| { (v.visit_ty)(a.ty, (copy e, v)); } - (v.visit_ty)(f.decl.output, (copy e, v)); + for f.decl.inputs.iter().advance |a| { (v.visit_ty)(&a.ty, (copy e, v)); } + (v.visit_ty)(&f.decl.output, (copy e, v)); do f.bounds.map |bounds| { visit_ty_param_bounds(bounds, (copy e, v)); }; }, ty_bare_fn(ref f) => { - for f.decl.inputs.iter().advance |a| { (v.visit_ty)(a.ty, (copy e, v)); } - (v.visit_ty)(f.decl.output, (e, v)); + for f.decl.inputs.iter().advance |a| { (v.visit_ty)(&a.ty, (copy e, v)); } + (v.visit_ty)(&f.decl.output, (e, v)); }, - ty_path(p, bounds, _) => { + ty_path(ref p, ref bounds, _) => { visit_path(p, (copy e, v)); do bounds.map |bounds| { visit_ty_param_bounds(bounds, (copy e, v)); @@ -269,12 +267,12 @@ pub fn visit_ty(t: &Ty, (e, v): (E, vt)) { } pub fn visit_path(p: &Path, (e, v): (E, vt)) { - for p.types.iter().advance |tp| { (v.visit_ty)(*tp, (copy e, v)); } + for p.types.iter().advance |tp| { (v.visit_ty)(tp, (copy e, v)); } } pub fn visit_pat(p: &pat, (e, v): (E, vt)) { match p.node { - pat_enum(path, ref children) => { + pat_enum(ref path, ref children) => { visit_path(path, (copy e, v)); for children.iter().advance |children| { for children.iter().advance |child| { @@ -282,7 +280,7 @@ pub fn visit_pat(p: &pat, (e, v): (E, vt)) { } } } - pat_struct(path, ref fields, _) => { + pat_struct(ref path, ref fields, _) => { visit_path(path, (copy e, v)); for fields.iter().advance |f| { (v.visit_pat)(f.pat, (copy e, v)); @@ -296,7 +294,7 @@ pub fn visit_pat(p: &pat, (e, v): (E, vt)) { pat_box(inner) | pat_uniq(inner) | pat_region(inner) => { (v.visit_pat)(inner, (e, v)) }, - pat_ident(_, path, ref inner) => { + pat_ident(_, ref path, ref inner) => { visit_path(path, (copy e, v)); for inner.iter().advance |subpat| { (v.visit_pat)(*subpat, (copy e, v)) @@ -328,7 +326,7 @@ pub fn visit_foreign_item(ni: &foreign_item, (e, v): (E, vt)) { visit_fn_decl(fd, (copy e, v)); (v.visit_generics)(generics, (e, v)); } - foreign_item_static(t, _) => { + foreign_item_static(ref t, _) => { (v.visit_ty)(t, (e, v)); } } @@ -338,7 +336,7 @@ pub fn visit_ty_param_bounds(bounds: &OptVec, (e, v): (E, vt)) { for bounds.iter().advance |bound| { match *bound { - TraitTyParamBound(ty) => visit_trait_ref(ty, (copy e, v)), + TraitTyParamBound(ref ty) => visit_trait_ref(ty, (copy e, v)), RegionTyParamBound => {} } } @@ -346,16 +344,16 @@ pub fn visit_ty_param_bounds(bounds: &OptVec, pub fn visit_generics(generics: &Generics, (e, v): (E, vt)) { for generics.ty_params.iter().advance |tp| { - visit_ty_param_bounds(tp.bounds, (copy e, v)); + visit_ty_param_bounds(&tp.bounds, (copy e, v)); } } pub fn visit_fn_decl(fd: &fn_decl, (e, v): (E, vt)) { for fd.inputs.iter().advance |a| { (v.visit_pat)(a.pat, (copy e, v)); - (v.visit_ty)(a.ty, (copy e, v)); + (v.visit_ty)(&a.ty, (copy e, v)); } - (v.visit_ty)(fd.output, (e, v)); + (v.visit_ty)(&fd.output, (e, v)); } // Note: there is no visit_method() method in the visitor, instead override @@ -386,9 +384,9 @@ pub fn visit_fn(fk: &fn_kind, decl: &fn_decl, body: &blk, _sp: span, } pub fn visit_ty_method(m: &ty_method, (e, v): (E, vt)) { - for m.decl.inputs.iter().advance |a| { (v.visit_ty)(a.ty, (copy e, v)); } + for m.decl.inputs.iter().advance |a| { (v.visit_ty)(&a.ty, (copy e, v)); } (v.visit_generics)(&m.generics, (copy e, v)); - (v.visit_ty)(m.decl.output, (e, v)); + (v.visit_ty)(&m.decl.output, (e, v)); } pub fn visit_trait_method(m: &trait_method, (e, v): (E, vt)) { @@ -411,16 +409,12 @@ pub fn visit_struct_def( } pub fn visit_struct_field(sf: &struct_field, (e, v): (E, vt)) { - (v.visit_ty)(sf.node.ty, (e, v)); -} - -pub fn visit_struct_method(m: &method, (e, v): (E, vt)) { - visit_method_helper(m, (e, v)); + (v.visit_ty)(&sf.node.ty, (e, v)); } pub fn visit_block(b: &blk, (e, v): (E, vt)) { for b.node.view_items.iter().advance |vi| { - (v.visit_view_item)(*vi, (copy e, v)); + (v.visit_view_item)(vi, (copy e, v)); } for b.node.stmts.iter().advance |s| { (v.visit_stmt)(*s, (copy e, v)); @@ -464,7 +458,7 @@ pub fn visit_expr(ex: @expr, (e, v): (E, vt)) { (v.visit_expr)(element, (copy e, v)); (v.visit_expr)(count, (copy e, v)); } - expr_struct(p, ref flds, base) => { + expr_struct(ref p, ref flds, base) => { visit_path(p, (copy e, v)); for flds.iter().advance |f| { (v.visit_expr)(f.node.expr, (copy e, v)); @@ -481,7 +475,7 @@ pub fn visit_expr(ex: @expr, (e, v): (E, vt)) { expr_method_call(_, callee, _, ref tys, ref args, _) => { visit_exprs(*args, (copy e, v)); for tys.iter().advance |tp| { - (v.visit_ty)(*tp, (copy e, v)); + (v.visit_ty)(tp, (copy e, v)); } (v.visit_expr)(callee, (copy e, v)); } @@ -492,7 +486,7 @@ pub fn visit_expr(ex: @expr, (e, v): (E, vt)) { expr_addr_of(_, x) | expr_unary(_, _, x) | expr_loop_body(x) | expr_do_body(x) => (v.visit_expr)(x, (copy e, v)), expr_lit(_) => (), - expr_cast(x, t) => { + expr_cast(x, ref t) => { (v.visit_expr)(x, (copy e, v)); (v.visit_ty)(t, (copy e, v)); } @@ -533,14 +527,14 @@ pub fn visit_expr(ex: @expr, (e, v): (E, vt)) { expr_field(x, _, ref tys) => { (v.visit_expr)(x, (copy e, v)); for tys.iter().advance |tp| { - (v.visit_ty)(*tp, (copy e, v)); + (v.visit_ty)(tp, (copy e, v)); } } expr_index(_, a, b) => { (v.visit_expr)(a, (copy e, v)); (v.visit_expr)(b, (copy e, v)); } - expr_path(p) => visit_path(p, (copy e, v)), + expr_path(ref p) => visit_path(p, (copy e, v)), expr_self => (), expr_break(_) => (), expr_again(_) => (), @@ -574,7 +568,7 @@ pub fn visit_arm(a: &arm, (e, v): (E, vt)) { pub struct SimpleVisitor { visit_mod: @fn(&_mod, span, node_id), - visit_view_item: @fn(@view_item), + visit_view_item: @fn(&view_item), visit_foreign_item: @fn(@foreign_item), visit_item: @fn(@item), visit_local: @fn(@local), @@ -585,7 +579,7 @@ pub struct SimpleVisitor { visit_decl: @fn(@decl), visit_expr: @fn(@expr), visit_expr_post: @fn(@expr), - visit_ty: @fn(@Ty), + visit_ty: @fn(&Ty), visit_generics: @fn(&Generics), visit_fn: @fn(&fn_kind, &fn_decl, &blk, span, node_id), visit_ty_method: @fn(&ty_method), @@ -597,7 +591,7 @@ pub struct SimpleVisitor { pub type simple_visitor = @SimpleVisitor; -pub fn simple_ignore_ty(_t: @Ty) {} +pub fn simple_ignore_ty(_t: &Ty) {} pub fn default_simple_visitor() -> @SimpleVisitor { @SimpleVisitor { @@ -635,7 +629,7 @@ pub fn mk_simple_visitor(v: simple_visitor) -> vt<()> { f(m, sp, id); visit_mod(m, sp, id, (e, v)); } - fn v_view_item(f: @fn(@view_item), vi: @view_item, (e, v): ((), vt<()>)) { + fn v_view_item(f: @fn(&view_item), vi: &view_item, (e, v): ((), vt<()>)) { f(vi); visit_view_item(vi, (e, v)); } @@ -678,7 +672,7 @@ pub fn mk_simple_visitor(v: simple_visitor) -> vt<()> { fn v_expr_post(f: @fn(@expr), ex: @expr, (_e, _v): ((), vt<()>)) { f(ex); } - fn v_ty(f: @fn(@Ty), ty: @Ty, (e, v): ((), vt<()>)) { + fn v_ty(f: @fn(&Ty), ty: &Ty, (e, v): ((), vt<()>)) { f(ty); visit_ty(ty, (e, v)); } @@ -723,16 +717,12 @@ pub fn mk_simple_visitor(v: simple_visitor) -> vt<()> { f(fk, decl, body, sp, id); visit_fn(fk, decl, body, sp, id, (e, v)); } - let visit_ty: @fn(@Ty, ((), vt<()>)) = + let visit_ty: @fn(&Ty, ((), vt<()>)) = |a,b| v_ty(v.visit_ty, a, b); fn v_struct_field(f: @fn(@struct_field), sf: @struct_field, (e, v): ((), vt<()>)) { f(sf); visit_struct_field(sf, (e, v)); } - fn v_struct_method(f: @fn(@method), m: @method, (e, v): ((), vt<()>)) { - f(m); - visit_struct_method(m, (e, v)); - } return mk_vt(@Visitor { visit_mod: |a,b,c,d|v_mod(v.visit_mod, a, b, c, d), visit_view_item: |a,b| v_view_item(v.visit_view_item, a, b), @@ -760,7 +750,5 @@ pub fn mk_simple_visitor(v: simple_visitor) -> vt<()> { v_struct_def(v.visit_struct_def, a, b, c, d, e), visit_struct_field: |a,b| v_struct_field(v.visit_struct_field, a, b), - visit_struct_method: |a,b| - v_struct_method(v.visit_struct_method, a, b) }); } diff --git a/src/rt/rust_uv.cpp b/src/rt/rust_uv.cpp index 32ccc9ba4a82..95e38a9903c4 100644 --- a/src/rt/rust_uv.cpp +++ b/src/rt/rust_uv.cpp @@ -13,10 +13,11 @@ #include #endif +#include "uv.h" + #include "rust_globals.h" #include "rust_task.h" #include "rust_log.h" -#include "uv.h" // extern fn pointers typedef void (*extern_async_op_cb)(uv_loop_t* loop, void* data, diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger index fbd687778ae7..9b8f0e3a4621 100644 --- a/src/rustllvm/llvm-auto-clean-trigger +++ b/src/rustllvm/llvm-auto-clean-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -6-29-2013 +2013-07-03 diff --git a/src/test/auxiliary/trait_default_method_xc_aux.rs b/src/test/auxiliary/trait_default_method_xc_aux.rs index 5ee243179df8..7ae648f113a3 100644 --- a/src/test/auxiliary/trait_default_method_xc_aux.rs +++ b/src/test/auxiliary/trait_default_method_xc_aux.rs @@ -1,5 +1,7 @@ #[allow(default_methods)]; +pub struct Something { x: int } + pub trait A { fn f(&self) -> int; fn g(&self) -> int { 10 } @@ -11,6 +13,10 @@ impl A for int { fn f(&self) -> int { 10 } } +impl A for Something { + fn f(&self) -> int { 10 } +} + trait B { fn thing(&self, x: T, y: U) -> (T, U) { (x, y) } } diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index c4d89a698c1a..867be38545cd 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -44,7 +44,7 @@ fn maybe_run_test(argv: &[~str], name: ~str, test: &fn()) { if os::getenv(~"RUST_BENCH").is_some() { run_test = true } else if argv.len() > 0 { - run_test = argv.iter().any_(|x| x == &~"all") || argv.iter().any_(|x| x == &name) + run_test = argv.iter().any(|x| x == &~"all") || argv.iter().any(|x| x == &name) } if !run_test { diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index bc5efc5fca1f..47de9334be15 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -95,13 +95,13 @@ fn make_graph(N: uint, edges: ~[(node_id, node_id)]) -> graph { } } - do vec::map_consume(graph) |mut v| { + do graph.consume_iter().transform |mut v| { let mut vec = ~[]; do v.consume |i| { vec.push(i); } vec - } + }.collect() } fn gen_search_keys(graph: &[~[node_id]], n: uint) -> ~[node_id] { @@ -111,7 +111,7 @@ fn gen_search_keys(graph: &[~[node_id]], n: uint) -> ~[node_id] { while keys.len() < n { let k = r.gen_uint_range(0u, graph.len()); - if graph[k].len() > 0u && graph[k].iter().any_(|i| { + if graph[k].len() > 0u && graph[k].iter().any(|i| { *i != k as node_id }) { keys.insert(k as node_id); @@ -187,7 +187,7 @@ fn bfs2(graph: graph, key: node_id) -> bfs_result { } let mut i = 0; - while colors.iter().any_(is_gray) { + while colors.iter().any(is_gray) { // Do the BFS. info!("PBFS iteration %?", i); i += 1; @@ -402,7 +402,7 @@ fn validate(edges: ~[(node_id, node_id)], if *v == -1i64 || u == root { true } else { - edges.iter().any_(|x| x == &(u, *v)) || edges.iter().any_(|x| x == &(*v, u)) + edges.iter().any(|x| x == &(u, *v)) || edges.iter().any(|x| x == &(*v, u)) } }; result diff --git a/src/test/bench/task-perf-alloc-unwind.rs b/src/test/bench/task-perf-alloc-unwind.rs index e245ab894f5b..abc44dfbc9bb 100644 --- a/src/test/bench/task-perf-alloc-unwind.rs +++ b/src/test/bench/task-perf-alloc-unwind.rs @@ -96,7 +96,7 @@ fn recurse_or_fail(depth: int, st: Option) { fn_box: || @Cons((), fn_box()), tuple: (@Cons((), st.tuple.first()), ~Cons((), @*st.tuple.second())), - vec: st.vec + [@Cons((), *st.vec.last())], + vec: st.vec + &[@Cons((), *st.vec.last())], res: r(@Cons((), st.res._l)) } } diff --git a/src/test/bench/task-perf-one-million.rs b/src/test/bench/task-perf-one-million.rs index e1366a3a8694..1cd90962c5b7 100644 --- a/src/test/bench/task-perf-one-million.rs +++ b/src/test/bench/task-perf-one-million.rs @@ -28,20 +28,21 @@ fn calc(children: uint, parent_wait_chan: &Chan>>) { wait_port }; - let child_start_chans: ~[Chan>] = vec::map_consume(wait_ports, |port| port.recv()); + let child_start_chans: ~[Chan>] = + wait_ports.consume_iter().transform(|port| port.recv()).collect(); let (start_port, start_chan) = stream::>(); parent_wait_chan.send(start_chan); let parent_result_chan: Chan = start_port.recv(); - let child_sum_ports: ~[Port] = do vec::map_consume(child_start_chans) |child_start_chan| { - let (child_sum_port, child_sum_chan) = stream::(); - child_start_chan.send(child_sum_chan); - child_sum_port - }; + let child_sum_ports: ~[Port] = + do child_start_chans.consume_iter().transform |child_start_chan| { + let (child_sum_port, child_sum_chan) = stream::(); + child_start_chan.send(child_sum_chan); + child_sum_port + }.collect(); - let mut sum = 0; - vec::consume(child_sum_ports, |_, sum_port| sum += sum_port.recv() ); + let sum = child_sum_ports.consume_iter().fold(0, |sum, sum_port| sum + sum_port.recv() ); parent_result_chan.send(sum + 1); } diff --git a/src/test/compile-fail/bad-env-capture.rs b/src/test/compile-fail/bad-env-capture.rs index c1eb39c466aa..ac5a4c220a4a 100644 --- a/src/test/compile-fail/bad-env-capture.rs +++ b/src/test/compile-fail/bad-env-capture.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: attempted dynamic environment-capture +// error-pattern: can't capture dynamic environment in a fn item; fn foo() { let x: int; fn bar() { log(debug, x); } diff --git a/src/test/compile-fail/bad-env-capture2.rs b/src/test/compile-fail/bad-env-capture2.rs index a6d4d71242b7..c97069acd9ae 100644 --- a/src/test/compile-fail/bad-env-capture2.rs +++ b/src/test/compile-fail/bad-env-capture2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: attempted dynamic environment-capture +// error-pattern: can't capture dynamic environment in a fn item; fn foo(x: int) { fn bar() { log(debug, x); } } diff --git a/src/test/compile-fail/bad-env-capture3.rs b/src/test/compile-fail/bad-env-capture3.rs index 9e26faf32e7c..e3a6ac2cdfc4 100644 --- a/src/test/compile-fail/bad-env-capture3.rs +++ b/src/test/compile-fail/bad-env-capture3.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: attempted dynamic environment-capture +// error-pattern: can't capture dynamic environment in a fn item; fn foo(x: int) { fn mth() { fn bar() { log(debug, x); } diff --git a/src/test/compile-fail/capture1.rs b/src/test/compile-fail/capture1.rs index 290dc7088822..706edd0a112b 100644 --- a/src/test/compile-fail/capture1.rs +++ b/src/test/compile-fail/capture1.rs @@ -10,7 +10,7 @@ // except according to those terms. -// error-pattern: attempted dynamic environment-capture +// error-pattern: can't capture dynamic environment in a fn item; fn main() { let bar: int = 5; diff --git a/src/test/compile-fail/circular_modules_hello.rs b/src/test/compile-fail/circular_modules_hello.rs new file mode 100644 index 000000000000..261fa489f610 --- /dev/null +++ b/src/test/compile-fail/circular_modules_hello.rs @@ -0,0 +1,17 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-test: this is an auxiliary file for circular-modules-main.rs + +mod circular_modules_main; + +pub fn say_hello() { + println(circular_modules_main::hi_str()); +} diff --git a/src/test/compile-fail/circular_modules_main.rs b/src/test/compile-fail/circular_modules_main.rs new file mode 100644 index 000000000000..06b5854f42c8 --- /dev/null +++ b/src/test/compile-fail/circular_modules_main.rs @@ -0,0 +1,20 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + + +mod circular_modules_hello; //~ERROR: circular modules + +pub fn hi_str() -> ~str { + ~"Hi!" +} + +fn main() { + circular_modules_hello::say_hello(); +} diff --git a/src/test/compile-fail/the-case-of-the-recurring-closure-2.rs b/src/test/compile-fail/closure-bounds-cant-mutably-borrow-with-copy.rs similarity index 100% rename from src/test/compile-fail/the-case-of-the-recurring-closure-2.rs rename to src/test/compile-fail/closure-bounds-cant-mutably-borrow-with-copy.rs diff --git a/src/test/compile-fail/issue-3021-b.rs b/src/test/compile-fail/issue-3021-b.rs index d3aec178c238..641403fb85a1 100644 --- a/src/test/compile-fail/issue-3021-b.rs +++ b/src/test/compile-fail/issue-3021-b.rs @@ -18,7 +18,7 @@ fn siphash(k0 : u64) { impl siphash { pub fn reset(&mut self) { - self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR attempted dynamic environment-capture + self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR can't capture dynamic environment //~^ ERROR unresolved name `k0`. } } diff --git a/src/test/compile-fail/issue-3021-d.rs b/src/test/compile-fail/issue-3021-d.rs index c6b5d8c42d59..c5ee9e8bb90e 100644 --- a/src/test/compile-fail/issue-3021-d.rs +++ b/src/test/compile-fail/issue-3021-d.rs @@ -30,9 +30,9 @@ fn siphash(k0 : u64, k1 : u64) -> siphash { impl siphash for SipState { fn reset(&self) { - self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR attempted dynamic environment-capture + self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR can't capture dynamic environment //~^ ERROR unresolved name `k0`. - self.v1 = k1 ^ 0x646f72616e646f6d; //~ ERROR attempted dynamic environment-capture + self.v1 = k1 ^ 0x646f72616e646f6d; //~ ERROR can't capture dynamic environment //~^ ERROR unresolved name `k1`. } fn result(&self) -> u64 { return mk_result(self); } diff --git a/src/test/compile-fail/issue-3021.rs b/src/test/compile-fail/issue-3021.rs index 0ca6173275cb..56ade814db02 100644 --- a/src/test/compile-fail/issue-3021.rs +++ b/src/test/compile-fail/issue-3021.rs @@ -21,7 +21,7 @@ fn siphash(k0 : u64) -> SipHash { impl SipHash for SipState { fn reset(&self) { - self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR attempted dynamic environment-capture + self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR can't capture dynamic environment //~^ ERROR unresolved name `k0`. } } diff --git a/src/test/compile-fail/issue-3044.rs b/src/test/compile-fail/issue-3044.rs index f4ae436c624d..310de3657b38 100644 --- a/src/test/compile-fail/issue-3044.rs +++ b/src/test/compile-fail/issue-3044.rs @@ -12,7 +12,7 @@ fn main() { let needlesArr: ~[char] = ~['a', 'f']; do needlesArr.iter().fold() |x, y| { } - //~^ ERROR 1 parameter was supplied (including the closure passed by the `do` keyword) + //~^^ ERROR 1 parameter was supplied (including the closure passed by the `do` keyword) // // the first error is, um, non-ideal. } diff --git a/src/test/compile-fail/lint-non-uppercase-statics.rs b/src/test/compile-fail/lint-non-uppercase-statics.rs new file mode 100644 index 000000000000..4da4d3ada384 --- /dev/null +++ b/src/test/compile-fail/lint-non-uppercase-statics.rs @@ -0,0 +1,15 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[forbid(non_uppercase_statics)]; + +static foo: int = 1; //~ ERROR static constant should have an uppercase identifier + +fn main() { } diff --git a/src/test/compile-fail/lint-unused-imports.rs b/src/test/compile-fail/lint-unused-imports.rs index e61de0ac11f4..e7e01a404872 100644 --- a/src/test/compile-fail/lint-unused-imports.rs +++ b/src/test/compile-fail/lint-unused-imports.rs @@ -30,7 +30,7 @@ use std::io::WriterUtil; // Make sure this import is warned about when at least one of its imported names // is unused -use std::vec::{filter, from_elem}; //~ ERROR unused import +use std::vec::{from_fn, from_elem}; //~ ERROR unused import mod foo { pub struct Point{x: int, y: int} diff --git a/src/test/compile-fail/the-case-of-the-recurring-closure.rs b/src/test/compile-fail/moves-based-on-type-no-recursive-stack-closure.rs similarity index 100% rename from src/test/compile-fail/the-case-of-the-recurring-closure.rs rename to src/test/compile-fail/moves-based-on-type-no-recursive-stack-closure.rs diff --git a/src/test/compile-fail/move-based-on-type-tuple.rs b/src/test/compile-fail/moves-based-on-type-tuple.rs similarity index 100% rename from src/test/compile-fail/move-based-on-type-tuple.rs rename to src/test/compile-fail/moves-based-on-type-tuple.rs diff --git a/src/test/compile-fail/resolve-unknown-trait.rs b/src/test/compile-fail/resolve-unknown-trait.rs new file mode 100644 index 000000000000..699a30ad4ebd --- /dev/null +++ b/src/test/compile-fail/resolve-unknown-trait.rs @@ -0,0 +1,20 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + + +trait NewTrait : SomeNonExistentTrait {} +//~^ ERROR attempt to derive a nonexistent trait `SomeNonExistentTrait` + +impl SomeNonExistentTrait for int {} +//~^ ERROR attempt to implement a nonexistent trait `SomeNonExistentTrait` + +fn f() {} +//~^ ERROR attempt to bound type parameter with a nonexistent trait `SomeNonExistentTrait` + diff --git a/src/test/compile-fail/static-assert.rs b/src/test/compile-fail/static-assert.rs index 06f8c9f1a325..019a4b88aedf 100644 --- a/src/test/compile-fail/static-assert.rs +++ b/src/test/compile-fail/static-assert.rs @@ -1,5 +1,5 @@ #[static_assert] -static a: bool = false; //~ ERROR static assertion failed +static A: bool = false; //~ ERROR static assertion failed fn main() { } diff --git a/src/test/compile-fail/static-assert2.rs b/src/test/compile-fail/static-assert2.rs index de1c6427e14b..42e475dac8b6 100644 --- a/src/test/compile-fail/static-assert2.rs +++ b/src/test/compile-fail/static-assert2.rs @@ -1,4 +1,4 @@ #[static_assert] -static e: bool = 1 == 2; //~ ERROR static assertion failed +static E: bool = 1 == 2; //~ ERROR static assertion failed fn main() {} diff --git a/src/test/pretty/block-comment-wchar.pp b/src/test/pretty/block-comment-wchar.pp index dbf28caecf29..c666950034a0 100644 --- a/src/test/pretty/block-comment-wchar.pp +++ b/src/test/pretty/block-comment-wchar.pp @@ -108,7 +108,6 @@ fn main() { '\xA0', '\u1680', '\u180E', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005', '\u2006', '\u2007', '\u2008', '\u2009', '\u200A', '\u2028', '\u2029', '\u202F', '\u205F', '\u3000']; - // <= bugs in pretty-printer? for chars.iter().advance |c| { let ws = c.is_whitespace(); println(fmt!("%? %?" , c , ws)); diff --git a/src/test/pretty/block-comment-wchar.rs b/src/test/pretty/block-comment-wchar.rs index 148b50d9c912..f0d46f39cdf9 100644 --- a/src/test/pretty/block-comment-wchar.rs +++ b/src/test/pretty/block-comment-wchar.rs @@ -104,6 +104,6 @@ fn main() { '\u2028', '\u2029', '\u202F', '\u205F', '\u3000']; for chars.iter().advance |c| { let ws = c.is_whitespace(); - println(fmt!("%? %?", c , ws)); // <= bugs in pretty-printer? + println(fmt!("%? %?", c , ws)); } } diff --git a/src/test/pretty/for-comment.rs b/src/test/pretty/for-comment.rs new file mode 100644 index 000000000000..15631337d2a4 --- /dev/null +++ b/src/test/pretty/for-comment.rs @@ -0,0 +1,18 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// pp-exact + +fn f(v: &[int]) { + let mut n = 0; + for v.iter().advance |e| { + n = *e; // This comment once triggered pretty printer bug + } +} diff --git a/src/test/run-fail/bug-2470-bounds-check-overflow.rs b/src/test/run-fail/bug-2470-bounds-check-overflow.rs index bd7d86d72953..0fdaf31c5936 100644 --- a/src/test/run-fail/bug-2470-bounds-check-overflow.rs +++ b/src/test/run-fail/bug-2470-bounds-check-overflow.rs @@ -11,7 +11,6 @@ // error-pattern:index out of bounds use std::sys; -use std::vec; fn main() { @@ -22,7 +21,7 @@ fn main() { // huge). let x = ~[1u,2u,3u]; - do vec::as_imm_buf(x) |p, _len| { + do x.as_imm_buf |p, _len| { let base = p as uint; let idx = base / sys::size_of::(); error!("ov1 base = 0x%x", base); diff --git a/src/test/run-pass/block-arg.rs b/src/test/run-pass/block-arg.rs index 8ea2a88fa09a..466f2def290b 100644 --- a/src/test/run-pass/block-arg.rs +++ b/src/test/run-pass/block-arg.rs @@ -20,20 +20,20 @@ pub fn main() { } // Usable at all: - let mut any_negative = do v.iter().any_ |e| { e.is_negative() }; + let mut any_negative = do v.iter().any |e| { e.is_negative() }; assert!(any_negative); // Higher precedence than assignments: - any_negative = do v.iter().any_ |e| { e.is_negative() }; + any_negative = do v.iter().any |e| { e.is_negative() }; assert!(any_negative); // Higher precedence than unary operations: let abs_v = do v.iter().transform |e| { e.abs() }.collect::<~[float]>(); assert!(do abs_v.iter().all |e| { e.is_positive() }); - assert!(!do abs_v.iter().any_ |e| { e.is_negative() }); + assert!(!do abs_v.iter().any |e| { e.is_negative() }); // Usable in funny statement-like forms: - if !do v.iter().any_ |e| { e.is_positive() } { + if !do v.iter().any |e| { e.is_positive() } { assert!(false); } match do v.iter().all |e| { e.is_negative() } { @@ -41,7 +41,7 @@ pub fn main() { false => { } } match 3 { - _ if do v.iter().any_ |e| { e.is_negative() } => { + _ if do v.iter().any |e| { e.is_negative() } => { } _ => { fail!("wrong answer."); @@ -58,7 +58,7 @@ pub fn main() { // In the tail of a block let w = - if true { do abs_v.iter().any_ |e| { e.is_positive() } } + if true { do abs_v.iter().any |e| { e.is_positive() } } else { false }; assert!(w); } diff --git a/src/test/run-pass/bug-7183-generics.rs b/src/test/run-pass/bug-7183-generics.rs index 4fc5587e7f36..532b2312a987 100644 --- a/src/test/run-pass/bug-7183-generics.rs +++ b/src/test/run-pass/bug-7183-generics.rs @@ -39,7 +39,6 @@ fn main() { assert_eq!(Some(Some(3)).hi(), ~"something!something!hello: 3"); assert_eq!(None::.hi(), ~"hello - none"); - // These fail because of a bug in monomorphization's ID generation. - //assert_eq!(Some(None::).hi(), ~"something!hello - none"); - //assert_eq!(Some(3).hi(), ~"something!hello: 3"); + assert_eq!(Some(None::).hi(), ~"something!hello - none"); + assert_eq!(Some(3).hi(), ~"something!hello: 3"); } diff --git a/src/test/run-pass/closure-bounds-recursive-stack-closure.rs b/src/test/run-pass/closure-bounds-recursive-stack-closure.rs new file mode 100644 index 000000000000..8bb57ebaaf58 --- /dev/null +++ b/src/test/run-pass/closure-bounds-recursive-stack-closure.rs @@ -0,0 +1,31 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Ensures that it's legal to create a recursive stack closure as long as +// its environment is copyable + +struct R<'self> { + // This struct is needed to create the + // otherwise infinite type of a fn that + // accepts itself as argument: + c: &'self fn:Copy(&R, uint) -> uint +} + +fn main() { + // Stupid version of fibonacci. + let fib: &fn:Copy(&R, uint) -> uint = |fib, x| { + if x == 0 || x == 1 { + x + } else { + (fib.c)(fib, x-1) + (fib.c)(fib, x-2) + } + }; + assert!(fib(&R { c: fib }, 7) == 13); +} diff --git a/src/test/run-pass/import-glob-crate.rs b/src/test/run-pass/import-glob-crate.rs index b036a57e19cb..d09ef3bc25c3 100644 --- a/src/test/run-pass/import-glob-crate.rs +++ b/src/test/run-pass/import-glob-crate.rs @@ -17,5 +17,5 @@ use std::vec::*; pub fn main() { let mut v = from_elem(0u, 0); v = append(v, ~[4, 2]); - assert_eq!(reversed(v), ~[2, 4]); + assert_eq!(from_fn(2, |i| 2*(i+1)), ~[2, 4]); } diff --git a/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs b/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs new file mode 100644 index 000000000000..8c1dc366f232 --- /dev/null +++ b/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs @@ -0,0 +1,21 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[forbid(non_camel_case_types)]; +#[forbid(non_uppercase_statics)]; + +// Some scripts (e.g. hiragana) don't have a concept of +// upper/lowercase + +struct ヒ; + +static ラ: uint = 0; + +fn main() {} diff --git a/src/test/run-pass/lint-non-uppercase-statics-lowercase-mut-statics.rs b/src/test/run-pass/lint-non-uppercase-statics-lowercase-mut-statics.rs new file mode 100644 index 000000000000..3a3648fbf6d8 --- /dev/null +++ b/src/test/run-pass/lint-non-uppercase-statics-lowercase-mut-statics.rs @@ -0,0 +1,17 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + + +#[forbid(non_camel_case_types)]; +#[forbid(non_uppercase_statics)]; + +static mut bar: int = 2; + +fn main() {} diff --git a/src/test/run-pass/newtype-temporary.rs b/src/test/run-pass/newtype-temporary.rs new file mode 100644 index 000000000000..d2407f3d6059 --- /dev/null +++ b/src/test/run-pass/newtype-temporary.rs @@ -0,0 +1,19 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Foo(uint); + +fn foo() -> Foo { + Foo(42) +} + +fn main() { + assert_eq!(*foo(), 42); +} diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index 176e49e0ea19..53b39d5ed303 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -232,6 +232,13 @@ impl TyVisitor for ptr_visit_adaptor { true } + fn visit_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool { + self.align_to::<~u8>(); + if ! self.inner.visit_uniq_managed(mtbl, inner) { return false; } + self.bump_past::<~u8>(); + true + } + fn visit_ptr(&self, mtbl: uint, inner: *TyDesc) -> bool { self.align_to::<*u8>(); if ! self.inner.visit_ptr(mtbl, inner) { return false; } @@ -552,6 +559,7 @@ impl TyVisitor for my_visitor { fn visit_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } fn visit_uniq(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_uniq_managed(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } fn visit_ptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } fn visit_rptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } diff --git a/src/test/run-pass/reflect-visit-type.rs b/src/test/run-pass/reflect-visit-type.rs index bb1c92dfa8a7..4ce229526ffb 100644 --- a/src/test/run-pass/reflect-visit-type.rs +++ b/src/test/run-pass/reflect-visit-type.rs @@ -70,6 +70,7 @@ impl TyVisitor for MyVisitor { fn visit_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } fn visit_uniq(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_uniq_managed(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } fn visit_ptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } fn visit_rptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } diff --git a/src/test/run-pass/test-ignore-cfg.rs b/src/test/run-pass/test-ignore-cfg.rs index e7a23244c06b..6e6670e4c38e 100644 --- a/src/test/run-pass/test-ignore-cfg.rs +++ b/src/test/run-pass/test-ignore-cfg.rs @@ -26,11 +26,11 @@ fn shouldnotignore() { #[test] fn checktests() { // Pull the tests out of the secreturn test module - let tests = __test::tests; + let tests = __test::TESTS; assert!( - tests.iter().any_(|t| t.desc.name.to_str() == ~"shouldignore" && t.desc.ignore)); + tests.iter().any(|t| t.desc.name.to_str() == ~"shouldignore" && t.desc.ignore)); assert!( - tests.iter().any_(|t| t.desc.name.to_str() == ~"shouldnotignore" && !t.desc.ignore)); + tests.iter().any(|t| t.desc.name.to_str() == ~"shouldnotignore" && !t.desc.ignore)); } diff --git a/src/test/run-pass/trait-default-method-xc.rs b/src/test/run-pass/trait-default-method-xc.rs index f6c119c4faeb..4eac1a1e7308 100644 --- a/src/test/run-pass/trait-default-method-xc.rs +++ b/src/test/run-pass/trait-default-method-xc.rs @@ -4,16 +4,18 @@ #[allow(default_methods)]; extern mod aux(name = "trait_default_method_xc_aux"); -use aux::{A, B, TestEquality}; +use aux::{A, B, TestEquality, Something}; fn f(i: T) { assert_eq!(i.g(), 10); } +mod stuff { + pub struct thing { x: int } +} -pub struct thing { x: int } -impl A for thing { +impl A for stuff::thing { fn f(&self) -> int { 10 } } @@ -29,8 +31,8 @@ fn neq(lhs: &T, rhs: &T) -> bool { } -impl TestEquality for thing { - fn test_eq(&self, rhs: &thing) -> bool { +impl TestEquality for stuff::thing { + fn test_eq(&self, rhs: &stuff::thing) -> bool { //self.x.test_eq(&rhs.x) eq(&self.x, &rhs.x) } @@ -41,15 +43,17 @@ fn main () { // Some tests of random things f(0); - let a = thing { x: 0 }; - let b = thing { x: 1 }; + let a = stuff::thing { x: 0 }; + let b = stuff::thing { x: 1 }; + let c = Something { x: 1 }; - //assert_eq!(0i.g(), 10); + assert_eq!(0i.g(), 10); assert_eq!(a.g(), 10); assert_eq!(a.h(), 10); + assert_eq!(c.h(), 10); - - //assert_eq!(0i.thing(3.14, 1), (3.14, 1)); + 0i.thing(3.14, 1); + assert_eq!(0i.thing(3.14, 1), (3.14, 1)); assert_eq!(g(0i, 3.14, 1), (3.14, 1)); assert_eq!(g(false, 3.14, 1), (3.14, 1)); @@ -59,8 +63,8 @@ fn main () { // Trying out a real one - //assert!(12.test_neq(&10)); - //assert!(!10.test_neq(&10)); + assert!(12.test_neq(&10)); + assert!(!10.test_neq(&10)); assert!(a.test_neq(&b)); assert!(!a.test_neq(&a)); diff --git a/src/test/run-pass/use.rs b/src/test/run-pass/use.rs index d73abc803cd5..e23fccb28f15 100644 --- a/src/test/run-pass/use.rs +++ b/src/test/run-pass/use.rs @@ -13,7 +13,7 @@ #[no_std]; extern mod std; extern mod zed(name = "std"); -extern mod bar(name = "std", vers = "0.7"); +extern mod bar(name = "std", vers = "0.8-pre"); use std::str;